summaryrefslogtreecommitdiff
path: root/lib/tsan
diff options
context:
space:
mode:
authorKuba Brecka <kuba.brecka@gmail.com>2016-04-07 11:52:51 +0000
committerKuba Brecka <kuba.brecka@gmail.com>2016-04-07 11:52:51 +0000
commitc81ba58d36a2b0566c738d47e3eea0663833e112 (patch)
tree1e9f9cb78670f1a4294766f1f17a16786e90dbdc /lib/tsan
parent0b468747e2765d6f465f8ddf433f26ab456d93a7 (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@265662 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan')
-rw-r--r--lib/tsan/rtl/tsan_libdispatch_mac.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/tsan/rtl/tsan_libdispatch_mac.cc b/lib/tsan/rtl/tsan_libdispatch_mac.cc
index abfc82fc3..9f92d5eb2 100644
--- a/lib/tsan/rtl/tsan_libdispatch_mac.cc
+++ b/lib/tsan/rtl/tsan_libdispatch_mac.cc
@@ -389,6 +389,40 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_registration_handler_f,
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