Workaround TSan false positives in add_to_black_list_normal/stack
authorIvan Maidanski <ivmai@mail.ru>
Fri, 1 Dec 2017 07:35:59 +0000 (10:35 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 1 Dec 2017 07:35:59 +0000 (10:35 +0300)
* 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
include/private/gc_priv.h

index c06fbdd..23d6a31 100644 (file)
@@ -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);
   }
 }
 
index 8a47bec..108bebc 100644 (file)
@@ -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
+
 
 /********************************************/
 /*                                          */