From 3aefd4e732f2894c31ee74315c3d65644a1f4ac1 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 21 Dec 2017 02:25:48 +0300 Subject: [PATCH] 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). --- src/atomic_ops_malloc.c | 7 +------ src/atomic_ops_stack.c | 17 ++++++++++++++++- 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 -- 2.40.0