Are atomic globals supposed to work?

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.

1 Like

There is currently a bug with address only noncopyable globals where borrowing uses are incorrectly treated as consumes.

Well this is because you're compiling it as an executable where all globals are eagerly initialized on program launch (see main). If you add -parse-as-library you can see that it is still lazily initialized. One of the things I wanted to look at doing was teaching the compiler that it can statically initialize atomics so that we don't have the overhead of swift_once on every access, but I have had other things taking up my time :sob:

6 Likes

This should now be resolved with SILGen: Emit references to noncopyable global storage directly as a borrow. by jckarter · Pull Request #73041 · apple/swift · GitHub. Hopefully we can get nightlies with this pretty soon :crossed_fingers:

1 Like