]> granicus.if.org Git - libatomic_ops/commitdiff
Workaround TSan false positive in AO_stack_pop_explicit_aux_acquire
authorIvan Maidanski <ivmai@mail.ru>
Wed, 20 Dec 2017 23:25:48 +0000 (02:25 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Wed, 20 Dec 2017 23:25:48 +0000 (02:25 +0300)
(fix commits c058d9d6ffda1db)

The TSan-related workaround in AO_malloc is no longer needed.

* src/atomic_ops_malloc.c [AO_THREAD_SANITIZER
&& AO_USE_ALMOST_LOCK_FREE] (AO_malloc): Do not use AO_store (always
use *result=log_sz); remove comment.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE
&& AO_THREAD_SANITIZER] (AO_load_next): New static function (with
AO_ATTR_NO_SANITIZE_THREAD attribute); add comments.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE
&& !AO_THREAD_SANITIZER] (AO_load_next): Define to AO_load.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE]
(AO_stack_pop_explicit_aux_acquire): Replace AO_load(first_ptr) with
AO_load_next(first_ptr).

src/atomic_ops_malloc.c
src/atomic_ops_stack.c

index a2016eab409b74f500ecc0fe954a62cea30cb908..f86585d43c70d2be888dce72ede9615b6a8364c5 100644 (file)
@@ -336,12 +336,7 @@ AO_malloc(size_t sz)
     add_chunk_as(chunk, log_sz);
     result = AO_stack_pop(AO_free_list+log_sz);
   }
-# if defined(AO_THREAD_SANITIZER) && defined(AO_USE_ALMOST_LOCK_FREE)
-    /* A data race with AO_stack_pop() called above is a false positive. */
-    AO_store(result, log_sz);
-# else
-    *result = log_sz;
-# endif
+  *result = log_sz;
 # ifdef AO_TRACE_MALLOC
     fprintf(stderr, "%p: AO_malloc(%lu) = %p\n",
             (void *)pthread_self(), (unsigned long)sz, (void *)(result + 1));
index 5219fdfa08a7039de5af65840fadcf732ea5dba2..e167d360c31119c6c68a089a2a84b2155425931a 100644 (file)
@@ -122,6 +122,21 @@ void AO_stack_push_explicit_aux_release(volatile AO_t *list, AO_t *x,
 # define PRECHECK(a)
 #endif
 
+/* This function is used before CAS in the below AO_stack_pop() and the */
+/* data race (reported by TSan) is OK because it results in a retry.    */
+#ifdef AO_THREAD_SANITIZER
+  AO_ATTR_NO_SANITIZE_THREAD
+  static AO_t AO_load_next(volatile AO_t *first_ptr)
+  {
+    /* Assuming an architecture on which loads of word type are atomic. */
+    /* AO_load cannot be used here because it cannot be instructed to   */
+    /* suppress the warning about the race.                             */
+    return *first_ptr;
+  }
+#else
+# define AO_load_next AO_load
+#endif
+
 AO_t *
 AO_stack_pop_explicit_aux_acquire(volatile AO_t *list, AO_stack_aux * a)
 {
@@ -176,7 +191,7 @@ AO_stack_pop_explicit_aux_acquire(volatile AO_t *list, AO_stack_aux * a)
     goto retry;
   }
   first_ptr = AO_REAL_NEXT_PTR(first);
-  next = AO_load(first_ptr);
+  next = AO_load_next(first_ptr);
 # if defined(__alpha__) && (__GNUC__ == 4)
     if (!AO_compare_and_swap_release(list, first, next))
 # else