The following doesn't work:
import Synchronization
@available(macOS 9999, *)
let lastTimestamp = Atomic<UInt64>(0)
@available(macOS 9999, *)
func test(_ newTimestamp: UInt64) -> UInt64 {
lastTimestamp.max(newTimestamp, ordering: .relaxed).newValue
}
<source>:8:3: error: 'lastTimestamp' is borrowed and cannot be consumed
6 │ @available(macOS 9999, *)
7 │ func test(_ newTimestamp: UInt64) -> UInt64 {
8 │ lastTimestamp.max(newTimestamp, ordering: .relaxed).newValue
│ ├─ error: 'lastTimestamp' is borrowed and cannot be consumed
│ ╰─ note: consumed here
9 │ }
Instead, I need to box the atomic inside a class for the compiler to be happy:
import Synchronization
class SharedData {
@available(macOS 9999, *)
let lastTimestamp = Atomic<UInt64>(0)
}
let sharedData = SharedData()
@available(macOS 9999, *)
func test(_ newTimestamp: UInt64) -> UInt64 {
sharedData.lastTimestamp.max(newTimestamp, ordering: .relaxed).newValue
}
I'm not entirely sure if this is a bug or an intentional limitation.
There doesn't seem to be any loss in efficiency - sharedData
is not lazily initialised, so test
can just access the location of the atomic directly (Godbolt) - but it is kind of annoying.