From 1dc2066460912e132e5aaf48eac30f6261ed23d9 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Fri, 1 Dec 2017 10:35:59 +0300 Subject: [PATCH] Workaround TSan false positives in add_to_black_list_normal/stack * blacklst.c (GC_add_to_black_list_normal, GC_add_to_black_list_stack): Call set_pht_entry_from_index_concurrent() instead of set_pht_entry_from_index(). * include/private/gc_priv.h [PARALLEL_MARK && THREAD_SANITIZER] (set_pht_entry_from_index_concurrent): New macro (use AO_or). * include/private/gc_priv.h [!PARALLEL_MARK || !THREAD_SANITIZER] (set_pht_entry_from_index_concurrent): Define to set_pht_entry_from_index. --- blacklst.c | 4 ++-- include/private/gc_priv.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/blacklst.c b/blacklst.c index c06fbdd..23d6a31 100644 --- a/blacklst.c +++ b/blacklst.c @@ -193,7 +193,7 @@ GC_INNER void GC_unpromote_black_lists(void) GC_print_blacklisted_ptr(p, source, "normal"); } # endif - set_pht_entry_from_index(GC_incomplete_normal_bl, index); + set_pht_entry_from_index_concurrent(GC_incomplete_normal_bl, index); } /* else this is probably just an interior pointer to an allocated */ /* object, and isn't worth black listing. */ } @@ -214,7 +214,7 @@ GC_INNER void GC_unpromote_black_lists(void) GC_print_blacklisted_ptr(p, source, "stack"); } # endif - set_pht_entry_from_index(GC_incomplete_stack_bl, index); + set_pht_entry_from_index_concurrent(GC_incomplete_stack_bl, index); } } diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 8a47bec..108bebc 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -928,6 +928,20 @@ typedef word page_hash_table[PHT_SIZE]; # define set_pht_entry_from_index_safe(bl, index) \ (bl)[divWORDSZ(index)] = ONES +/* And, one more version for GC_add_to_black_list_normal/stack. */ +/* The latter ones are invoked (indirectly) by GC_do_local_mark. */ +#if defined(PARALLEL_MARK) && defined(THREAD_SANITIZER) +# define set_pht_entry_from_index_concurrent(bl, index) \ + AO_or((volatile AO_t *)&(bl)[divWORDSZ(index)], \ + (AO_t)((word)1 << modWORDSZ(index))) +#else + /* It is safe to set a bit in a blacklist even without */ + /* synchronization, the only drawback is that we might have */ + /* to redo blacklisting sometimes. */ +# define set_pht_entry_from_index_concurrent(bl, index) \ + set_pht_entry_from_index(bl, index) +#endif + /********************************************/ /* */ -- 2.7.4