Undefined linker error when using 16-byte CAS with GCC

I use GCC 4.7.2 on Debian and get linker errors whenever I try to use <atomic> objects with 16 byte values. I am running VMware x86_64, which can support the CMPXCHG16B instruction, but even if I did not have the necessary hardware, I don’t understand why a linker error should be generated here. As far as I know, the <atomic> library should return to using regular locks if the hardware does not support the necessary CAS operation.

Anyway, here is a very simple test case to reproduce this problem:

 #include <atomic> #include <cstdint> struct foo { std::uint64_t x; std::uint64_t y; }; int main() { std::atomic<foo> f1({0,0}); foo f2 = {0,0}; foo f3 = {1,1}; f1.compare_exchange_strong(f2, f3); } 

When I compile this, I get:

 # g++ test.cpp -o test -std=c++11 -g3 /tmp/ccziKZis.o: In function `std::atomic<foo>::compare_exchange_strong(foo&, foo, std::memory_order, std::memory_order)': /usr/include/c++/4.7/atomic:259: undefined reference to `__atomic_compare_exchange_16' collect2: error: ld returned 1 exit status 

Please note that if I change the program so that foo only 8 bytes, I do not get a linker error. What's going on here?

+5
source share
1 answer

The simple answer if you know this:

Call g++ with -mcx16 .

G ++ docs say:

This parameter will allow GCC to use the CMPXCHG16B instruction in the generated code. CMPXCHG16B allows atomic operations on 128-bit binary words with a double square (or tin). This is useful for high resolution counters that can be updated by multiple processors (or cores). This instruction is generated as part of the atomic built-in functions: see the Atomic Builtins :: note for details.

(Note that this does not work for clang - I think this is a mistake!)

+6
source

Source: https://habr.com/ru/post/1206006/


All Articles