The attached patch fixes a race condition in libgomp. Based on the suggestions 
by Dmitry, and verified that it fixes the corresponding sanitizer warnings. 

2012-12-30  Dmitry Vyukov  <dvyu...@gcc.gnu.org>

        PR libgomp/55561
        * config/linux/wait.h (do_spin): Use atomic load for addr.
        * config/linux/ptrlock.c (gomp_ptrlock_get_slow): Use atomic
        for intptr and ptrlock.
        * onfig/linux/ptrlock.h (gomp_ptrlock_get): Use atomic load
        for ptrlock.



Index: libgomp/config/linux/wait.h
===================================================================
--- libgomp/config/linux/wait.h	(revision 194730)
+++ libgomp/config/linux/wait.h	(working copy)
@@ -51,7 +51,7 @@ static inline int do_spin (int *addr, in
   if (__builtin_expect (gomp_managed_threads > gomp_available_cpus, 0))
     count = gomp_throttled_spin_count_var;
   for (i = 0; i < count; i++)
-    if (__builtin_expect (*addr != val, 0))
+    if (__builtin_expect (__atomic_load_n (addr, MEMMODEL_RELAXED) != val, 0))
       return 0;
     else
       cpu_relax ();
Index: libgomp/config/linux/ptrlock.c
===================================================================
--- libgomp/config/linux/ptrlock.c	(revision 194730)
+++ libgomp/config/linux/ptrlock.c	(working copy)
@@ -50,9 +50,9 @@ gomp_ptrlock_get_slow (gomp_ptrlock_t *p
 #endif
   do
     do_wait (intptr, 2);
-  while (*intptr == 2);
+  while (__atomic_load_n (intptr, MEMMODEL_RELAXED) == 2);
   __asm volatile ("" : : : "memory");
-  return *ptrlock;
+  return (void *) __atomic_load_n (ptrlock, MEMMODEL_ACQUIRE);
 }
 
 void
Index: libgomp/config/linux/ptrlock.h
===================================================================
--- libgomp/config/linux/ptrlock.h	(revision 194730)
+++ libgomp/config/linux/ptrlock.h	(working copy)
@@ -48,8 +48,9 @@ static inline void *gomp_ptrlock_get (go
 {
   uintptr_t oldval;
 
-  if ((uintptr_t) *ptrlock > 2)
-    return *ptrlock;
+  uintptr_t v = (uintptr_t) __atomic_load_n (ptrlock, MEMMODEL_ACQUIRE);
+  if (v > 2)
+    return (void *) v;
 
   oldval = 0;
   if (__atomic_compare_exchange_n (ptrlock, &oldval, 1, false,

Reply via email to