[compiler-rt] r287902 - [tsan] Add support for GCD dispatch_suspend and dispatch_resume

Kuba Mracek via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 24 13:24:54 PST 2016


Author: kuba.brecka
Date: Thu Nov 24 15:24:54 2016
New Revision: 287902

URL: http://llvm.org/viewvc/llvm-project?rev=287902&view=rev
Log:
[tsan] Add support for GCD dispatch_suspend and dispatch_resume

GCD queues can be suspended and resumed with dispatch_suspend and dispatch_resume. We need to add synchronization between the call to dispatch_resume and any subsequent executions of blocks in the queue that was resumed. We already have an Acquire(q) before the block executes, so this patch just adds the Release(q) in an interceptor of dispatch_resume.

Differential Revision: https://reviews.llvm.org/D27112


Added:
    compiler-rt/trunk/test/tsan/Darwin/gcd-suspend.mm
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc?rev=287902&r1=287901&r2=287902&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc Thu Nov 24 15:24:54 2016
@@ -706,6 +706,15 @@ TSAN_INTERCEPTOR(void, dispatch_io_close
   return REAL(dispatch_io_close)(channel, flags);
 }
 
+// Resuming a suspended queue needs to synchronize with all subsequent
+// executions of blocks in that queue.
+TSAN_INTERCEPTOR(void, dispatch_resume, dispatch_object_t o) {
+  SCOPED_TSAN_INTERCEPTOR(dispatch_resume, o);
+  Release(thr, pc, (uptr)o);  // Synchronizes with the Acquire() on serial_sync
+                              // in dispatch_sync_pre_execute
+  return REAL(dispatch_resume)(o);
+}
+
 }  // namespace __tsan
 
 #endif  // SANITIZER_MAC

Added: compiler-rt/trunk/test/tsan/Darwin/gcd-suspend.mm
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/Darwin/gcd-suspend.mm?rev=287902&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/Darwin/gcd-suspend.mm (added)
+++ compiler-rt/trunk/test/tsan/Darwin/gcd-suspend.mm Thu Nov 24 15:24:54 2016
@@ -0,0 +1,45 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+long my_global = 0;
+
+int main(int argc, const char *argv[]) {
+  fprintf(stderr, "Hello world.\n");
+
+  dispatch_queue_t q1 = dispatch_queue_create("queue1", NULL);
+  dispatch_queue_t q2 = dispatch_queue_create("queue2", NULL);
+  dispatch_group_t g = dispatch_group_create();
+
+  dispatch_sync(q1, ^{
+    dispatch_suspend(q1);
+    dispatch_async(q2, ^{
+      my_global++;
+      dispatch_resume(q1);
+    });
+  });
+
+  dispatch_sync(q1, ^{
+    my_global++;
+  });
+
+  dispatch_sync(q1, ^{
+    dispatch_suspend(q1);
+    dispatch_group_enter(g);
+    dispatch_async(q1,^{ my_global++; });
+    dispatch_async(q1,^{ my_global++; });
+    dispatch_async(q1,^{ my_global++; dispatch_group_leave(g); });
+    my_global++;
+    dispatch_resume(q1);
+  });
+
+  dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+
+  fprintf(stderr, "Done.\n");
+  return 0;
+}
+
+// CHECK: Hello world.
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK: Done.




More information about the llvm-commits mailing list