https://swift.org/blog/swift-atomics/
I’m delighted to announce Swift Atomics, a new open source package that enables direct use of low-level atomic operations in Swift code. The goal of this library is to enable intrepid systems programmers to start building synchronization constructs (such as concurrent data structures) directly in Swift.
As a quick taste, this is what atomic operations look like using this new package:
import Atomics
import Dispatch
let counter = ManagedAtomic<Int>(0)
DispatchQueue.concurrentPerform(iterations: 10) { _ in
for _ in 0 ..< 1_000_000 {
counter.wrappingIncrement(by: 1, ordering: .relaxed)
}
}
counter.load(ordering: .relaxed) // ⟹ 10_000_000
You may have noticed that the atomic operations in this example do not follow the exclusivity rules that govern normal Swift variables. Atomic operations may be performed from multiple concurrent threads of execution, so long as the value is only accessed via atomic operations.
This is enabled by SE-0282, a recently accepted Swift Evolution proposal that explicitly adopted a C/C++-style memory model for Swift, and (informally) described how regular Swift code interoperates with atomic operations. In fact, most APIs in this new package come from previous incarnations of the SE-0282 proposal: they were originally developed by an extremely productive collaborative effort on the Evolution forum. I am deeply grateful to all contributors to these discussions, and I hope the package will continue the collaboration in similarly high spirits!
The Atomics package provides carefully considered API for atomic operations that follows established design principles for Swift APIs. However, the underlying operations work on a very low level of abstraction. Atomics – even more than other low-level concurrency constructs – are notoriously difficult to use correctly.
These APIs enable systems programming use cases that were previously out of reach for Swift programmers. In particular, atomics enable the creation of higher-level, easier-to-use constructs for managing concurrency without resorting to importing their implementation from another language.
Like unsafe APIs in the Standard Library, we recommend using this package very sparingly – preferably not at all! If it’s necessary, though, it is a good idea to:
Approach atomic code with extreme caution. Use copious amounts of Thread Sanitizer after every contact!
The package implements atomic operations for the following Swift types, all of which conform to the public AtomicValue protocol:
Int, Int64, Int32, Int16, Int8)UInt, UInt64, UInt32, UInt16, UInt8)Bool)