https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122078
--- Comment #3 from Federico Terraneo <fede.tft at miosix dot org> --- (In reply to Richard Biener from comment #1) > libatomic isn't a fallback for targets not having atomics at all. That was my impression by reading the documentation: https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_concurrency_impl.html "Current releases use the newer __atomic intrinsics, which are implemented by library calls if the hardware doesn't support them. Undefined references to functions like __atomic_is_lock_free should be resolved by linking to libatomic" That to me looks like a fallback for hardware that does not have atomic instructions. > Note it > still makes sense to have multi-byte "bools", so the set of functions make > sense as well as not having __atomic_test_and_set_n. My comment for multi-byte "bools" is related to the fact that a grep in the entire GCC source code found no use of them. Who uses them? > > Please provide a testcase that shows what you observe. Ok. We are developing the Miosix free software RTOS for microcontrollers. We already patch libatomic so our OS sycnhronization primitives are called on architectures lacking atomic operations. The bug is not related to our patches as libatomic has not even a chance to get involved, as it does not provide the __atomic_test_and_set symbol. Moreover, other RTOS targets have independently reported the same issue (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118977, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118280). The bug we are observing happens with the Raspberry Pi RP2040 SoC, it's a dual-core ARM Cortex-M0+ microcontroller, that lacks atomic operations. The simplest test case I could produce is the following: #include <future> int main() { std::future<int> fut = std::async(std::launch::async, []{ return 0; }); return fut.get(); } This code inlines code from the following header file: include/c++/14.2.0/bits/atomic_base.h:226 which indeed uses the __atomic_test_and_set intrinisic. If the code is compiled with -mthumb -mcpu=cortex-m0plus (the CPU with no atomic instructions) the main function ends up containing the following call: bl __atomic_test_and_set which then fails at the linking stage as this symbol is not provided by libatomic. ld: main.o: in function `_ZNSt11atomic_flag12test_and_setESt12memory_order': include/c++/14.2.0/bits/atomic_base.h:226:(.text.startup.main+0xc2): undefined reference to `__atomic_test_and_set' ld: (__atomic_test_and_set): Unknown destination type (ARM/Thumb) in main.o include/c++/14.2.0/bits/atomic_base.h:226:(.text.startup.main+0xc2): dangerous relocation: unsupported relocation collect2: error: ld returned 1 exit status If instead the code is compiled with -mthumb -mcpu=cortex-m3 (another CPU we support with atomic instructions) the compiler does not generate any call to __atomic_test_and_set and instead produces the following code: .L602: ldrexb r3, [r2] strexb r0, r1, [r2] cmp r0, #0 bne .L602 I'm attaching the full assembly files to have a look. Our opinion on the matter is that either libatomic should provide the __atomic_test_and_set symbol, or GCC should emit a call to __atomic_test_and_set_1, a symbol libatomic already provides (the arguments passed should also be checked for consistency in this case, we have not yet done so).
