diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2017-12-01 10:35:59 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2017-12-01 10:35:59 +0300 |
commit | 1dc2066460912e132e5aaf48eac30f6261ed23d9 (patch) | |
tree | eaaeb17a711bd2bef8c9d0ef9d345d9bf80838fa | |
parent | 236aeca34ea59db3f57fc1bcbb01e4e8672e409f (diff) | |
download | bdwgc-1dc2066460912e132e5aaf48eac30f6261ed23d9.tar.gz |
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.
-rw-r--r-- | blacklst.c | 4 | ||||
-rw-r--r-- | include/private/gc_priv.h | 14 |
2 files changed, 16 insertions, 2 deletions
@@ -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 8a47bec7..108bebc8 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 + /********************************************/ /* */ |