From: Ivan Maidanski Date: Wed, 22 Nov 2017 22:58:40 +0000 (+0300) Subject: Workaround TSan false positives for at-fork handlers accessing lock_holder X-Git-Tag: v8.0.0~498 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3a524692806bde17a7b668f96c0a687f653f3a21;p=platform%2Fupstream%2Flibgc.git Workaround TSan false positives for at-fork handlers accessing lock_holder * pthread_support.c (GC_wait_for_gc_completion): Skip I_HOLD_LOCK() assertion if THREAD_SANITIZER and CAN_HANDLE_FORK; add comment. * pthread_support.c [CAN_HANDLE_FORK && GC_ASSERTIONS] (fork_prepare_proc, fork_parent_proc, fork_child_proc): Add GC_ATTR_NO_SANITIZE_THREAD attribute. --- diff --git a/pthread_support.c b/pthread_support.c index 90602de..70b512a 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -1001,7 +1001,11 @@ STATIC void GC_remove_all_threads_but_me(void) STATIC void GC_wait_for_gc_completion(GC_bool wait_for_all) { DCL_LOCK_STATE; - GC_ASSERT(I_HOLD_LOCK()); +# if !defined(THREAD_SANITIZER) || !defined(CAN_HANDLE_FORK) + /* GC_lock_holder is accessed with the lock held, so there is no */ + /* data race actually (unlike what is reported by TSan). */ + GC_ASSERT(I_HOLD_LOCK()); +# endif ASSERT_CANCEL_DISABLED(); if (GC_incremental && GC_collection_in_progress()) { word old_gc_no = GC_gc_no; @@ -1035,6 +1039,10 @@ IF_CANCEL(static int fork_cancel_state;) /* protected by allocation lock. */ /* Called before a fork() */ +#ifdef GC_ASSERTIONS + /* GC_lock_holder is updated safely (no data race actually). */ + GC_ATTR_NO_SANITIZE_THREAD +#endif static void fork_prepare_proc(void) { /* Acquire all relevant locks, so that after releasing the locks */ @@ -1059,6 +1067,9 @@ static void fork_prepare_proc(void) } /* Called in parent after a fork() (even if the latter failed). */ +#ifdef GC_ASSERTIONS + GC_ATTR_NO_SANITIZE_THREAD +#endif static void fork_parent_proc(void) { # if defined(PARALLEL_MARK) @@ -1070,6 +1081,9 @@ static void fork_parent_proc(void) } /* Called in child after a fork() */ +#ifdef GC_ASSERTIONS + GC_ATTR_NO_SANITIZE_THREAD +#endif static void fork_child_proc(void) { /* Clean up the thread table, so that just our thread is left. */