From: Ivan Maidanski Date: Fri, 1 Dec 2017 08:48:08 +0000 (+0300) Subject: Workaround TSan warning about data race in generic_malloc_many X-Git-Tag: v8.0.0~465 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=31cc9697e40ad05bf92b9570211ad4dd902fc0cc;p=gc Workaround TSan warning about data race in generic_malloc_many It is acceptable to update GC_bytes_found counter without synchronization (so, it is OK to have inaccurate value in GC_bytes_found in favor of performance). * mallocx.c [PARALLEL_MARK && THREAD_SANITIZER] (GC_generic_malloc_many): Acquire the allocation lock to update GC_bytes_found (after successful GC_reclaim_generic). * mallocx.c [PARALLEL_MARK && !THREAD_SANITIZER] (GC_generic_malloc_many): Move GC_bytes_found update into the block executed with the mark lock held. --- diff --git a/mallocx.c b/mallocx.c index a38653c9..242804a6 100644 --- a/mallocx.c +++ b/mallocx.c @@ -357,11 +357,6 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result) op = GC_reclaim_generic(hbp, hhdr, lb, ok -> ok_init, 0, &my_bytes_allocd); if (op != 0) { - /* We also reclaimed memory, so we need to adjust */ - /* that count. */ - /* This should be atomic, so the results may be */ - /* inaccurate. */ - GC_bytes_found += my_bytes_allocd; # ifdef PARALLEL_MARK if (GC_parallel) { *result = op; @@ -370,11 +365,23 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result) GC_acquire_mark_lock(); -- GC_fl_builder_count; if (GC_fl_builder_count == 0) GC_notify_all_builder(); - GC_release_mark_lock(); +# ifdef THREAD_SANITIZER + GC_release_mark_lock(); + LOCK(); + GC_bytes_found += my_bytes_allocd; + UNLOCK(); +# else + GC_bytes_found += my_bytes_allocd; + /* The result may be inaccurate. */ + GC_release_mark_lock(); +# endif (void) GC_clear_stack(0); return; } # endif + /* We also reclaimed memory, so we need to adjust */ + /* that count. */ + GC_bytes_found += my_bytes_allocd; GC_bytes_allocd += my_bytes_allocd; goto out; }