From 8a2ca6bb41fa07701f92e56d3d508e4dbbecc733 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 16 Oct 2026 09:15:34 +0200 Subject: [PATCH] Add missing compiler barriers to include/atomic.h (bug 34748) Barriers were missing from atomic_forced_read, atomic_load_relaxed, atomic_store_relaxed. The easiest way to get them is to use volatile accesses. This was observed as a test hang in nptl/tst-rwlock9. The test ended up spinning in __pthread_rwlock_rdlock_full64: /* We still need to wait for explicit hand-over, but we must not use futex_wait anymore because we would just time out in this case and thus make the spin-waiting we need unnecessarily expensive. */ while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex) | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) { /* TODO Back-off? */ } GCC hoisted the load out of the loop. Reviewed-by: Carlos O'Donell --- include/atomic.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/include/atomic.h b/include/atomic.h index 16b36d80f1..126485e3e0 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -520,8 +520,7 @@ #ifndef atomic_forced_read -# define atomic_forced_read(x) \ - ({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; }) +# define atomic_forced_read(x) (*((volatile __typeof (x) *) &(x))) #endif /* This is equal to 1 iff the architecture supports 64b atomic operations. */ @@ -666,10 +665,7 @@ void __atomic_link_error (void); # endif # ifndef atomic_load_relaxed -# define atomic_load_relaxed(mem) \ - ({ __typeof ((__typeof (*(mem))) *(mem)) __atg100_val; \ - __asm ("" : "=r" (__atg100_val) : "0" (*(mem))); \ - __atg100_val; }) +# define atomic_load_relaxed(mem) (*((volatile __typeof (*mem) *) (mem))) # endif # ifndef atomic_load_acquire # define atomic_load_acquire(mem) \ @@ -679,8 +675,8 @@ void __atomic_link_error (void); # endif # ifndef atomic_store_relaxed -/* XXX Use inline asm here? */ -# define atomic_store_relaxed(mem, val) do { *(mem) = (val); } while (0) +# define atomic_store_relaxed(mem, val) \ + do { *((volatile __typeof (*mem) *) (mem)) = (val); } while (0) # endif # ifndef atomic_store_release # define atomic_store_release(mem, val) \