Workaround TSan false positive in invoke_finalizers
authorIvan Maidanski <ivmai@mail.ru>
Mon, 30 Oct 2017 22:09:56 +0000 (01:09 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 31 Oct 2017 21:18:33 +0000 (00:18 +0300)
* finalize.c [THREADS && !THREAD_SANITIZER] (GC_invoke_finalizers): Do
not compare bytes_freed_before to GC_bytes_freed without the lock; add
comment.
* include/private/gc_priv.h (_GC_arrays._finalizer_bytes_freed): Replace
"mem." to "memory" in a comment.

finalize.c
include/private/gc_priv.h

index 0c39b54..aaed8d4 100644 (file)
@@ -1224,7 +1224,15 @@ GC_API int GC_CALL GC_invoke_finalizers(void)
         /* finalizable.  Otherwise it should not matter.        */
     }
     /* bytes_freed_before is initialized whenever count != 0 */
-    if (count != 0 && bytes_freed_before != GC_bytes_freed) {
+    if (count != 0
+#         if defined(THREADS) && !defined(THREAD_SANITIZER)
+            /* A quick check whether some memory was freed.     */
+            /* The race with GC_free() is safe to be ignored    */
+            /* because we only need to know if the current      */
+            /* thread has deallocated something.                */
+            && bytes_freed_before != GC_bytes_freed
+#         endif
+       ) {
         LOCK();
         GC_finalizer_bytes_freed += (GC_bytes_freed - bytes_freed_before);
         UNLOCK();
index 7fc977d..e10bcfd 100644 (file)
@@ -1224,7 +1224,7 @@ struct _GC_arrays {
         /* since last collection.                               */
   word _finalizer_bytes_freed;
         /* Bytes of memory explicitly deallocated while         */
-        /* finalizers were running.  Used to approximate mem.   */
+        /* finalizers were running.  Used to approximate memory */
         /* explicitly deallocated by finalizers.                */
   ptr_t _scratch_end_ptr;
   ptr_t _scratch_last_end_ptr;