I feel like I must be missing something everyone else is seeing.
Below is the standard simplest example of using an atomic as a counter. I just ran this in a playground using the tip of main on swift-atomics and verified it works as expected.
If the ManagedAtomic in this example becomes AtomicValue<T>: ~Copyable
type (as clearly discussed in this thread), how can I access that Atomic<Int>
from two different Tasks concurrently to increment the counter? If the answer is: "you can't" then when would I ever use a ~Copyable Atomic? And how would I modify this code using borrowing/consuming to achieve the concurrency this requires?
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
import Atomics
class IntRef { var i: Int = 0 }
let atomicValue: ManagedAtomic<Int> = .init(0)
let nonatomicValue: IntRef = .init()
Task {
let t1 = Task<Void, Never> {
for i in 0 ..< 100_000 {
atomicValue.wrappingIncrementThenLoad(by: 1, ordering: .relaxed)
nonatomicValue.i += 1
}
}
let t2 = Task<Void, Never> {
for i in 0 ..< 100_000 {
atomicValue.wrappingIncrementThenLoad(by: 1, ordering: .relaxed)
nonatomicValue.i += 1
}
}
await t1.value
await t2.value
print("done. atomicValue = \(atomicValue.load(ordering: .relaxed)), nonatomicValue = \(nonatomicValue.i)")
PlaygroundPage.current.finishExecution()
}