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 <carlos@redhat.com>
This commit is contained in:
Florian Weimer
2026-10-17 17:47:10 +02:00
parent e39d4ded3f
commit 8a2ca6bb41
+4 -8
View File
@@ -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) \