Sound usage of UnsafeAtomic's pointer based init

swift-atomics has the ManagedAtomic type for maximum safety, and the UnsafeAtomic type for more manual management.

Intuitively it feels like it should be possible to work with a simple atomic counter without allocating storage dynamically (via either type), but I'm not sure how to ensure that its sound as I've written it using the UnsafeAtomic.init(at:) initializer.

import Atomics

struct Ids {
    static var generator = Int32.AtomicRepresentation(0)

    func nextId() -> Int32 {
        withUnsafeMutablePointer(to: &Self.generator) { ptr in
            let atomic = UnsafeAtomic<Int32>(at: ptr)
            return atomic.wrappingIncrementThenLoad(ordering: .relaxed)
        }
    }
}

Using an inout via withUnsafeMutablePointer to get the pointer feels particularly dangerous.

1 Like

Right, this doesn't work, because passing a parameter inout asserts exclusive access to it, and you don't want that for an atomic. Prior to Swift 6, you need to use manually-allocated memory for anything atomic. In Swift 6, you can use the standard library Atomic and Mutex types, which don't require an external allocation.

4 Likes

Is that in a different package? I don't see an AtomicInt type in swift-atomics

That's what I suspected, thank you for confirming!