[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