Swift-atomics: no way to enable AtomicReference on linux?

the motivation for this post is trying to add the swift-mongodb library to the swift package index.

so far, i have been getting along with enabling AtomicReference using custom build flags:

$ swift build -Xcc -mcx16 -Xswiftc -DENABLE_DOUBLEWIDE_ATOMICS -c release

that workflow had issues (VSCode does not like build flags, for example), but i didn’t consider them serious until i discovered the build flags mean that swift-mongodb’s builds will always fail on swiftpackageindex.com. so now i have been looking for a way to get the package to build without custom flags.

one idea i got from reaching out to @finestructure was to vend a custom copy of Atomics and _AtomicsShims patched to not require the custom build flags in the first place. this works for Atomics itself, because i can rename the module to avoid conflict with SwiftNIO’s Atomics dependency. (hooray!) but it does not work for _AtomicsShims, because _AtomicsShims is a C module, and all the symbols inside of it still collide with SwiftNIO’s _AtomicsShims dependency.

/swift/swift-mongodb/.build/checkouts/swift-atomics/Sources/_AtomicsShims/include/_AtomicsShims.h:353:1: error: '_sa_prepare_DoubleWord' has different definitions in different modules; definition in module '_AtomicsShims' first difference is function body
SWIFTATOMIC_DEFINE_TYPE(COMPLEX, DoubleWord, _sa_dword, _sa_double_word_ctype)
^
/swift/swift-mongodb/.build/checkouts/swift-atomics/Sources/_AtomicsShims/include/_AtomicsShims.h:248:3: note: expanded from macro 'SWIFTATOMIC_DEFINE_TYPE'
  SWIFTATOMIC_PREPARE_FN(swiftType, cType, storageType)                \
  ^
/swift/swift-mongodb/.build/checkouts/swift-atomics/Sources/_AtomicsShims/include/_AtomicsShims.h:108:19: note: expanded from macro 'SWIFTATOMIC_PREPARE_FN'
  _sa_##swiftType _sa_prepare_##swiftType(cType value)                  \
                  ^
<scratch space>:48:1: note: expanded from here
_sa_prepare_DoubleWord
^
/swift/swift-mongodb/Sources/AtomicReferenceShims/include/_AtomicsShims.h:353:1: note: but in 'AtomicReferenceShims' found a different body
SWIFTATOMIC_DEFINE_TYPE(COMPLEX, DoubleWord, _sa_dword, _sa_double_word_ctype)
^
/swift/swift-mongodb/Sources/AtomicReferenceShims/include/_AtomicsShims.h:248:3: note: expanded from macro 'SWIFTATOMIC_DEFINE_TYPE'
  SWIFTATOMIC_PREPARE_FN(swiftType, cType, storageType)                \
  ^
/swift/swift-mongodb/Sources/AtomicReferenceShims/include/_AtomicsShims.h:108:19: note: expanded from macro 'SWIFTATOMIC_PREPARE_FN'
  _sa_##swiftType _sa_prepare_##swiftType(cType value)                  \
                  ^
<scratch space>:39:1: note: expanded from here
_sa_prepare_DoubleWord
^

is there seriously no way to get AtomicReference compiling out-of-the-box ?

1 Like

If you're going to add new C functions, you have to change their namespace. This is an unavoidable rule. You can add prefixes to all the types in your fork and the problem will be resolved.

_AtomicsShims is a heavily macro'd C module and i have to admit i don't understand its internal workings very well.

i was able to patch it to get AtomicReference working because the #if #else blocks stand out. but unfortunately i have no clue how its API is generated, it uses a lot of macro magic.

@lorentey, I vaguely recall that we had fixed the Linux driver such that this was no longer needed; am I imagining that?

it is not needed, but there is a check for __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 in _AtomicsShims.h that disables it anyway.

here is a PR that removes it: enable AtomicReference everywhere by kelvin13 · Pull Request #65 · apple/swift-atomics · GitHub