summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2017-12-21 02:25:48 +0300
committerIvan Maidanski <ivmai@mail.ru>2017-12-21 02:25:48 +0300
commit3aefd4e732f2894c31ee74315c3d65644a1f4ac1 (patch)
treeb55769b5629ae8d29e868f16d71b34f156ac471d /src
parentca02cd7b1434107ca470f62cb046d1595d5a2a84 (diff)
downloadlibatomic_ops-3aefd4e732f2894c31ee74315c3d65644a1f4ac1.tar.gz
Workaround TSan false positive in AO_stack_pop_explicit_aux_acquire
(fix commits c058d9d, 6ffda1db) 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).
Diffstat (limited to 'src')
-rw-r--r--src/atomic_ops_malloc.c7
-rw-r--r--src/atomic_ops_stack.c17
2 files changed, 17 insertions, 7 deletions
diff --git a/src/atomic_ops_malloc.c b/src/atomic_ops_malloc.c
index a2016ea..f86585d 100644
--- a/src/atomic_ops_malloc.c
+++ b/src/atomic_ops_malloc.c
@@ -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));
diff --git a/src/atomic_ops_stack.c b/src/atomic_ops_stack.c
index 5219fdf..e167d36 100644
--- a/src/atomic_ops_stack.c
+++ b/src/atomic_ops_stack.c
@@ -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