summaryrefslogtreecommitdiff
path: root/test/tsan/Darwin
diff options
context:
space:
mode:
authorKuba Brecka <kuba.brecka@gmail.com>2016-07-07 12:38:37 +0000
committerKuba Brecka <kuba.brecka@gmail.com>2016-07-07 12:38:37 +0000
commite6b095b92f0c28c8398460f63899ab1af5450c05 (patch)
tree0402238ddad192d644cd0584c260a463e18edc10 /test/tsan/Darwin
parent4f47f51e687aaf4ea749e0cc72e4a1dc60e4ae95 (diff)
[tsan] Avoid false positives with GCD data callbacks
This patch adds synchronization between the creation of the GCD data object and destructor’s execution. It’s far from perfect, because ideally we’d want to synchronize the destruction of the last reference (via dispatch_release) and the destructor’s execution, but intercepting objc_release is problematic. Differential Revision: http://reviews.llvm.org/D21990 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@274749 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/tsan/Darwin')
-rw-r--r--test/tsan/Darwin/gcd-data.mm36
1 files changed, 36 insertions, 0 deletions
diff --git a/test/tsan/Darwin/gcd-data.mm b/test/tsan/Darwin/gcd-data.mm
new file mode 100644
index 000000000..a5154dc35
--- /dev/null
+++ b/test/tsan/Darwin/gcd-data.mm
@@ -0,0 +1,36 @@
+// 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 global;
+
+int main(int argc, const char *argv[]) {
+ fprintf(stderr, "Hello world.\n");
+
+ dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);
+ dispatch_semaphore_t sem = dispatch_semaphore_create(0);
+
+ global = 44;
+ dispatch_data_t data = dispatch_data_create("buffer", 6, q, ^{
+ fprintf(stderr, "Data destructor.\n");
+ global++;
+
+ dispatch_semaphore_signal(sem);
+ });
+ dispatch_release(data);
+ data = nil;
+
+ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
+
+ data = dispatch_data_create("buffer", 6, q, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
+ dispatch_release(data);
+ data = nil;
+
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: Data destructor.
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK: Done.