[backport proposed 4.8 fix for __cxa_guard_aqcuire ] From: Thiago Macieira Subject: [PATCH, libstdc++] Use acquire semantics in case of CAS failure Date: Thu, 30 Aug 2012 12:47:50 +0200 List-Id: Hello I detected this issue as I was updating the patches to send to the mailing list. I have not created a bug report. When the CAS operation fails and expected == guard_bit, __cxa_guard_acquire will return immediately indicating that the initialisation has already succeeded. However, it's missing the acquire barrier for the changes done on the other thread, to match the release barrier from __cxa_guard_release. That is: thread A thread B load.acq == 0 load.acq == 0 __cxa_guard_acquire __cxa_guard_acquire CAS(0 -> 256) success __cxa_guard_release store.rel(1) CAS(0 ->256) fails At this point, we must synchronise with the store-release from thread A. 2012-08-30 Thiago Macieira * libsupc++/guard.cc (__cxa_guard_acquire): must use acquire semantics in case of failure, to acquire changes done by the other thread --- gcc-4.7.1/libstdc++-v3/libsupc++/guard.cc.~1~ 2012-09-08 22:13:06.000000000 +0200 +++ gcc-4.7.1/libstdc++-v3/libsupc++/guard.cc 2012-09-08 22:16:41.000000000 +0200 @@ -253,7 +253,7 @@ namespace __cxxabiv1 int expected(0); if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false, __ATOMIC_ACQ_REL, - __ATOMIC_RELAXED)) + __ATOMIC_ACQUIRE)) { // This thread should do the initialization. return 1;