6

Previously, with Apple LLVM 9.1.0, is_lock_free() on 128-bit structures have returned true. To have complete std::optional support, I then upgraded to MacPorts gcc 7.3. During my first try to compile, I encountered this notorious showstopper linker error:

Undefined symbols for architecture x86_64:
  "___atomic_compare_exchange_16", referenced from:

I know that I may need to add -latomic. With Apple LLVM 9.1.0, I don't need it, and I have a very bad feeling about this. If it's lock-free, you usually should not need to link to any additional library, the compiler alone is able to handle it. Otherwise, it may just be lock-based and require support from additional library. Just as I have feared, after adding -latomic, build succeeded, but is_lock_free() returned false.

I do think gcc 7.3 and its standard library implementation are fine. It may just be some configuration problem on my side. As a matter of fact, I didn't do any configuration. I simply installed the MacPorts gcc and done. Any idea what I may be missing?

Lingxi
  • 14,579
  • 2
  • 37
  • 93

1 Answers1

3

Found the answer myself here.

gcc7 and later will call libatomic instead of inlining lock cmpxchg16b, and will return false from atomic_is_lock_free (for reasons including that it's so slow it's not what users expect is_lock_free to mean), but at least for now the libatomic implementation still uses lock cmpxchg16b on targets where that instruction is available. (It can even segfault for read-only atomic objects, so it's really not ideal.)

Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • Yup. 128-bit lock-free was always a little weird because `-mcx16` was required to inline `lock cmpxchg16b`. But apparently even on older gcc, you'd get `lock cmpxchg16b` in libatomic if supported, with runtime CPU detection I guess. (https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02344.html). I didn't check; that's based on the wording of Torvald Riegel's message about the patch that implemented the change. – Peter Cordes Apr 15 '18 at 21:06
  • @PeterCordes The thing is, even with `-mcx16`, `is_lock_free()` will return false (not inlined). I will write a runtime test function to genuinely check whether it is lock-free, and will update the answer then. – Lingxi Apr 16 '18 at 01:40
  • I was talking about gcc6 and earlier. That's why I said "was" (i.e. before that patch), but I should have been explicit with the start of my previous comment. On gcc6 and earlier with `-mcx16`, `is_lock_free` and `is_always_lock_free` reports true for 16-byte objects. Without `-mcx16`, I'm not sure; `is_lock_free` may check at runtime for `lock cmpxchg16b` support. But `always_lock_free` would be false. – Peter Cordes Apr 16 '18 at 02:02