1 | // RUN: %clang_tsan %s -o %t -framework Foundation |
2 | // RUN: %deflake %run %t 2>&1 | FileCheck %s |
3 | |
4 | #import <Foundation/Foundation.h> |
5 | |
6 | #import "../test.h" |
7 | |
8 | @interface MyClass : NSObject { |
9 | long instance_variable; |
10 | } |
11 | - (void)method:(long)value; |
12 | @end |
13 | |
14 | @implementation MyClass |
15 | |
16 | - (void)method:(long)value { |
17 | self->instance_variable = value; |
18 | } |
19 | |
20 | @end |
21 | |
22 | int main() { |
23 | NSLog(@"Hello world." ); |
24 | barrier_init(barrier: &barrier, count: 2); |
25 | |
26 | MyClass *my_object = [MyClass new]; |
27 | [my_object method:42]; |
28 | |
29 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
30 | [my_object method:43]; |
31 | barrier_wait(barrier: &barrier); |
32 | }); |
33 | |
34 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
35 | barrier_wait(barrier: &barrier); |
36 | [my_object method:44]; |
37 | |
38 | dispatch_sync(dispatch_get_main_queue(), ^{ |
39 | CFRunLoopStop(CFRunLoopGetCurrent()); |
40 | }); |
41 | }); |
42 | |
43 | CFRunLoopRun(); |
44 | NSLog(@"Done." ); |
45 | return 0; |
46 | } |
47 | |
48 | // CHECK: Hello world. |
49 | // CHECK: WARNING: ThreadSanitizer: data race |
50 | // CHECK: Write of size 8 |
51 | // CHECK: #0 -[MyClass method:] |
52 | // CHECK: Previous write of size 8 |
53 | // CHECK: #0 -[MyClass method:] |
54 | // CHECK: Location is heap block |
55 | // CHECK: Done. |
56 | |