[compiler-rt] r265662 - [tsan] Add interceptors for dispatch_apply

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 7 04:52:54 PDT 2016


Author: kuba.brecka
Date: Thu Apr  7 06:52:51 2016
New Revision: 265662

URL: http://llvm.org/viewvc/llvm-project?rev=265662&view=rev
Log:
[tsan] Add interceptors for dispatch_apply

Adding an interceptor with two more release+acquire pairs to avoid false positives with dispatch_apply.

Differential Revision: http://reviews.llvm.org/D18722


Added:
    compiler-rt/trunk/test/tsan/Darwin/gcd-apply-race.mm
    compiler-rt/trunk/test/tsan/Darwin/gcd-apply.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=265662&r1=265661&r2=265662&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc Thu Apr  7 06:52:51 2016
@@ -389,6 +389,40 @@ TSAN_INTERCEPTOR(void, dispatch_source_s
   WRAP(dispatch_source_set_registration_handler)(source, block);
 }
 
+TSAN_INTERCEPTOR(void, dispatch_apply, size_t iterations,
+                 dispatch_queue_t queue, void (^block)(size_t)) {
+  SCOPED_TSAN_INTERCEPTOR(dispatch_apply, iterations, queue, block);
+
+  void *parent_to_child_sync = nullptr;
+  uptr parent_to_child_sync_uptr = (uptr)&parent_to_child_sync;
+  void *child_to_parent_sync = nullptr;
+  uptr child_to_parent_sync_uptr = (uptr)&child_to_parent_sync;
+
+  Release(thr, pc, parent_to_child_sync_uptr);
+  void (^new_block)(size_t) = ^(size_t iteration) {
+    SCOPED_INTERCEPTOR_RAW(dispatch_apply);
+    Acquire(thr, pc, parent_to_child_sync_uptr);
+    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
+    block(iteration);
+    SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
+    Release(thr, pc, child_to_parent_sync_uptr);
+  };
+  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
+  REAL(dispatch_apply)(iterations, queue, new_block);
+  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
+  Acquire(thr, pc, child_to_parent_sync_uptr);
+}
+
+TSAN_INTERCEPTOR(void, dispatch_apply_f, size_t iterations,
+                 dispatch_queue_t queue, void *context,
+                 void (*work)(void *, size_t)) {
+  SCOPED_TSAN_INTERCEPTOR(dispatch_apply_f, iterations, queue, context, work);
+  void (^new_block)(size_t) = ^(size_t iteration) {
+    work(context, iteration);
+  };
+  WRAP(dispatch_apply)(iterations, queue, new_block);
+}
+
 }  // namespace __tsan
 
 #endif  // SANITIZER_MAC

Added: compiler-rt/trunk/test/tsan/Darwin/gcd-apply-race.mm
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/Darwin/gcd-apply-race.mm?rev=265662&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/Darwin/gcd-apply-race.mm (added)
+++ compiler-rt/trunk/test/tsan/Darwin/gcd-apply-race.mm Thu Apr  7 06:52:51 2016
@@ -0,0 +1,26 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 not %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main(int argc, const char *argv[]) {
+  barrier_init(&barrier, 2);
+  fprintf(stderr, "start\n");
+  dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
+  dispatch_apply(2, q, ^(size_t i) {
+    global = i;
+    barrier_wait(&barrier);
+  });
+
+  fprintf(stderr, "done\n");
+  return 0;
+}
+
+// CHECK: start
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'global'
+// CHECK: done

Added: compiler-rt/trunk/test/tsan/Darwin/gcd-apply.mm
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/Darwin/gcd-apply.mm?rev=265662&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/Darwin/gcd-apply.mm (added)
+++ compiler-rt/trunk/test/tsan/Darwin/gcd-apply.mm Thu Apr  7 06:52:51 2016
@@ -0,0 +1,44 @@
+// 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>
+
+#import "../test.h"
+
+long global;
+long array[2];
+
+void callback(void *context, size_t i) {
+  long n = global;
+  array[i] = n + i;
+  barrier_wait(&barrier);
+}
+
+int main(int argc, const char *argv[]) {
+  barrier_init(&barrier, 2);
+  fprintf(stderr, "start\n");
+  dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
+
+  global = 42;
+
+  dispatch_apply(100, q, ^(size_t i) {
+    long n = global;
+    array[i] = n + i;
+    barrier_wait(&barrier);
+  });
+
+  for (int i = 0; i < 100; i++) {
+    fprintf(stderr, "array[%d] = %ld\n", i, array[i]);
+  }
+
+  global = 43;
+
+  dispatch_apply_f(100, q, NULL, &callback);
+
+  fprintf(stderr, "done\n");
+  return 0;
+}
+
+// CHECK: start
+// CHECK: done
+// CHECK-NOT: WARNING: ThreadSanitizer




More information about the llvm-commits mailing list