annotate libsanitizer/tsan/tsan_interceptors_libdispatch.cpp @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 //===-- tsan_interceptors_libdispatch.cpp ---------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 // Support for intercepting libdispatch (GCD).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 #include "sanitizer_common/sanitizer_common.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 #include "interception/interception.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "tsan_interceptors.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "tsan_rtl.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "BlocksRuntime/Block.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "tsan_dispatch_defs.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 namespace __tsan {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 typedef u16 uint16_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 typedef struct {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 dispatch_queue_t queue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 void *orig_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 dispatch_function_t orig_work;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 bool free_context_in_callback;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 bool submitted_synchronously;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 bool is_barrier_block;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 uptr non_queue_sync_object;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 } block_context_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 // The offsets of different fields of the dispatch_queue_t structure, exported
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 // by libdispatch.dylib.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 extern "C" struct dispatch_queue_offsets_s {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 const uint16_t dqo_version;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 const uint16_t dqo_label;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 const uint16_t dqo_label_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 const uint16_t dqo_flags;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 const uint16_t dqo_flags_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 const uint16_t dqo_serialnum;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 const uint16_t dqo_serialnum_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 const uint16_t dqo_width;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 const uint16_t dqo_width_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 const uint16_t dqo_running;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 const uint16_t dqo_running_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 const uint16_t dqo_suspend_cnt;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 const uint16_t dqo_suspend_cnt_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 const uint16_t dqo_target_queue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 const uint16_t dqo_target_queue_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 const uint16_t dqo_priority;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 const uint16_t dqo_priority_size;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 } dispatch_queue_offsets;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 static bool IsQueueSerial(dispatch_queue_t q) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 CHECK_EQ(dispatch_queue_offsets.dqo_width_size, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 uptr width = *(uint16_t *)(((uptr)q) + dispatch_queue_offsets.dqo_width);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 CHECK_NE(width, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 return width == 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 static dispatch_queue_t GetTargetQueueFromQueue(dispatch_queue_t q) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 CHECK_EQ(dispatch_queue_offsets.dqo_target_queue_size, 8);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 dispatch_queue_t tq = *(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 dispatch_queue_t *)(((uptr)q) + dispatch_queue_offsets.dqo_target_queue);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 return tq;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 static dispatch_queue_t GetTargetQueueFromSource(dispatch_source_t source) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 dispatch_queue_t tq = GetTargetQueueFromQueue((dispatch_queue_t)source);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 CHECK_NE(tq, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 return tq;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 static block_context_t *AllocContext(ThreadState *thr, uptr pc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 dispatch_queue_t queue, void *orig_context,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 dispatch_function_t orig_work) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 block_context_t *new_context =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 (block_context_t *)user_alloc_internal(thr, pc, sizeof(block_context_t));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 new_context->queue = queue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 new_context->orig_context = orig_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 new_context->orig_work = orig_work;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 new_context->free_context_in_callback = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 new_context->submitted_synchronously = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 new_context->is_barrier_block = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 new_context->non_queue_sync_object = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 return new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 #define GET_QUEUE_SYNC_VARS(context, q) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 bool is_queue_serial = q && IsQueueSerial(q); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 uptr sync_ptr = (uptr)q ?: context->non_queue_sync_object; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 uptr serial_sync = (uptr)sync_ptr; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 uptr concurrent_sync = sync_ptr ? ((uptr)sync_ptr) + sizeof(uptr) : 0; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 bool serial_task = context->is_barrier_block || is_queue_serial
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 static void dispatch_sync_pre_execute(ThreadState *thr, uptr pc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 block_context_t *context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 uptr submit_sync = (uptr)context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 Acquire(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 dispatch_queue_t q = context->queue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 do {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 GET_QUEUE_SYNC_VARS(context, q);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 if (serial_sync) Acquire(thr, pc, serial_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 if (serial_task && concurrent_sync) Acquire(thr, pc, concurrent_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 if (q) q = GetTargetQueueFromQueue(q);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 } while (q);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 static void dispatch_sync_post_execute(ThreadState *thr, uptr pc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 block_context_t *context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 uptr submit_sync = (uptr)context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 if (context->submitted_synchronously) Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 dispatch_queue_t q = context->queue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 do {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 GET_QUEUE_SYNC_VARS(context, q);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 if (serial_task && serial_sync) Release(thr, pc, serial_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 if (!serial_task && concurrent_sync) Release(thr, pc, concurrent_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 if (q) q = GetTargetQueueFromQueue(q);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 } while (q);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 static void dispatch_callback_wrap(void *param) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 SCOPED_INTERCEPTOR_RAW(dispatch_callback_wrap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 block_context_t *context = (block_context_t *)param;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 dispatch_sync_pre_execute(thr, pc, context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 context->orig_work(context->orig_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 dispatch_sync_post_execute(thr, pc, context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 if (context->free_context_in_callback) user_free(thr, pc, context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 static void invoke_block(void *param) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 dispatch_block_t block = (dispatch_block_t)param;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 block();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 static void invoke_and_release_block(void *param) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 dispatch_block_t block = (dispatch_block_t)param;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 block();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 Block_release(block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 #define DISPATCH_INTERCEPT_ASYNC_B(name, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, dispatch_block_t block) { \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 SCOPED_TSAN_INTERCEPTOR(name, q, block); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 dispatch_block_t heap_block = Block_copy(block); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 block_context_t *new_context = \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 new_context->is_barrier_block = barrier; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 Release(thr, pc, (uptr)new_context); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 REAL(name##_f)(q, new_context, dispatch_callback_wrap); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 #define DISPATCH_INTERCEPT_SYNC_B(name, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 DISPATCH_NOESCAPE dispatch_block_t block) { \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 SCOPED_TSAN_INTERCEPTOR(name, q, block); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 block_context_t new_context = { \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 q, block, &invoke_block, false, true, barrier, 0}; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 Release(thr, pc, (uptr)&new_context); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 REAL(name##_f)(q, &new_context, dispatch_callback_wrap); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 Acquire(thr, pc, (uptr)&new_context); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 #define DISPATCH_INTERCEPT_ASYNC_F(name, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 dispatch_function_t work) { \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 block_context_t *new_context = \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 AllocContext(thr, pc, q, context, work); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 new_context->is_barrier_block = barrier; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 Release(thr, pc, (uptr)new_context); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 REAL(name)(q, new_context, dispatch_callback_wrap); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 #define DISPATCH_INTERCEPT_SYNC_F(name, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 dispatch_function_t work) { \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 block_context_t new_context = { \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 q, context, work, false, true, barrier, 0}; \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 Release(thr, pc, (uptr)&new_context); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 REAL(name)(q, &new_context, dispatch_callback_wrap); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 Acquire(thr, pc, (uptr)&new_context); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 #define DISPATCH_INTERCEPT(name, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 DISPATCH_INTERCEPT_ASYNC_F(name##_async_f, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 DISPATCH_INTERCEPT_ASYNC_B(name##_async, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 DISPATCH_INTERCEPT_SYNC_F(name##_sync_f, barrier) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 DISPATCH_INTERCEPT_SYNC_B(name##_sync, barrier)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 // We wrap dispatch_async, dispatch_sync and friends where we allocate a new
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 // context, which is used to synchronize (we release the context before
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 // submitting, and the callback acquires it before executing the original
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 // callback).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 DISPATCH_INTERCEPT(dispatch, false)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 DISPATCH_INTERCEPT(dispatch_barrier, true)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 DECLARE_REAL(void, dispatch_after_f, dispatch_time_t when,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 dispatch_queue_t queue, void *context, dispatch_function_t work)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 TSAN_INTERCEPTOR(void, dispatch_after, dispatch_time_t when,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 dispatch_queue_t queue, dispatch_block_t block) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 SCOPED_TSAN_INTERCEPTOR(dispatch_after, when, queue, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 dispatch_block_t heap_block = Block_copy(block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 block_context_t *new_context =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 AllocContext(thr, pc, queue, heap_block, &invoke_and_release_block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 Release(thr, pc, (uptr)new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 REAL(dispatch_after_f)(when, queue, new_context, dispatch_callback_wrap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 TSAN_INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 dispatch_queue_t queue, void *context,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 dispatch_function_t work) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 SCOPED_TSAN_INTERCEPTOR(dispatch_after_f, when, queue, context, work);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 WRAP(dispatch_after)(when, queue, ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 work(context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 // GCD's dispatch_once implementation has a fast path that contains a racy read
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 // and it's inlined into user's code. Furthermore, this fast path doesn't
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 // establish a proper happens-before relations between the initialization and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 // code following the call to dispatch_once. We could deal with this in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 // instrumented code, but there's not much we can do about it in system
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 // libraries. Let's disable the fast path (by never storing the value ~0 to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 // predicate), so the interceptor is always called, and let's add proper release
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 // and acquire semantics. Since TSan does not see its own atomic stores, the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 // race on predicate won't be reported - the only accesses to it that TSan sees
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 // are the loads on the fast path. Loads don't race. Secondly, dispatch_once is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 // both a macro and a real function, we want to intercept the function, so we
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 // need to undefine the macro.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 #undef dispatch_once
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 TSAN_INTERCEPTOR(void, dispatch_once, dispatch_once_t *predicate,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 DISPATCH_NOESCAPE dispatch_block_t block) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 SCOPED_INTERCEPTOR_RAW(dispatch_once, predicate, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 atomic_uint32_t *a = reinterpret_cast<atomic_uint32_t *>(predicate);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 u32 v = atomic_load(a, memory_order_acquire);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 if (v == 0 &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 atomic_compare_exchange_strong(a, &v, 1, memory_order_relaxed)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 block();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 Release(thr, pc, (uptr)a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 atomic_store(a, 2, memory_order_release);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 } else {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 while (v != 2) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 internal_sched_yield();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 v = atomic_load(a, memory_order_acquire);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 Acquire(thr, pc, (uptr)a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 #undef dispatch_once_f
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 TSAN_INTERCEPTOR(void, dispatch_once_f, dispatch_once_t *predicate,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 void *context, dispatch_function_t function) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 SCOPED_INTERCEPTOR_RAW(dispatch_once_f, predicate, context, function);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 WRAP(dispatch_once)(predicate, ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 function(context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 TSAN_INTERCEPTOR(long_t, dispatch_semaphore_signal,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 dispatch_semaphore_t dsema) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 SCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_signal, dsema);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 Release(thr, pc, (uptr)dsema);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 return REAL(dispatch_semaphore_signal)(dsema);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 TSAN_INTERCEPTOR(long_t, dispatch_semaphore_wait, dispatch_semaphore_t dsema,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 dispatch_time_t timeout) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 SCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_wait, dsema, timeout);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 long_t result = REAL(dispatch_semaphore_wait)(dsema, timeout);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 if (result == 0) Acquire(thr, pc, (uptr)dsema);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 TSAN_INTERCEPTOR(long_t, dispatch_group_wait, dispatch_group_t group,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 dispatch_time_t timeout) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 SCOPED_TSAN_INTERCEPTOR(dispatch_group_wait, group, timeout);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 long_t result = REAL(dispatch_group_wait)(group, timeout);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 if (result == 0) Acquire(thr, pc, (uptr)group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 // Used, but not intercepted.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 extern "C" void dispatch_group_enter(dispatch_group_t group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 TSAN_INTERCEPTOR(void, dispatch_group_leave, dispatch_group_t group) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 SCOPED_TSAN_INTERCEPTOR(dispatch_group_leave, group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 // Acquired in the group notification callback in dispatch_group_notify[_f].
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 Release(thr, pc, (uptr)group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 REAL(dispatch_group_leave)(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 TSAN_INTERCEPTOR(void, dispatch_group_async, dispatch_group_t group,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 dispatch_queue_t queue, dispatch_block_t block) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 SCOPED_TSAN_INTERCEPTOR(dispatch_group_async, group, queue, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 dispatch_retain(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 dispatch_group_enter(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 __block dispatch_block_t block_copy = (dispatch_block_t)Block_copy(block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 WRAP(dispatch_async)(queue, ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 block_copy();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 Block_release(block_copy);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 WRAP(dispatch_group_leave)(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 dispatch_release(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 TSAN_INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 dispatch_queue_t queue, void *context,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 dispatch_function_t work) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 SCOPED_TSAN_INTERCEPTOR(dispatch_group_async_f, group, queue, context, work);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 dispatch_retain(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 dispatch_group_enter(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 WRAP(dispatch_async)(queue, ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 work(context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 WRAP(dispatch_group_leave)(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 dispatch_release(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 DECLARE_REAL(void, dispatch_group_notify_f, dispatch_group_t group,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 dispatch_queue_t q, void *context, dispatch_function_t work)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 dispatch_queue_t q, dispatch_block_t block) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 // To make sure the group is still available in the callback (otherwise
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 // it can be already destroyed). Will be released in the callback.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 dispatch_retain(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 dispatch_block_t heap_block = Block_copy(^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 SCOPED_INTERCEPTOR_RAW(dispatch_read_callback);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 // Released when leaving the group (dispatch_group_leave).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 Acquire(thr, pc, (uptr)group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 dispatch_release(group);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 block();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 block_context_t *new_context =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 AllocContext(thr, pc, q, heap_block, &invoke_and_release_block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 new_context->is_barrier_block = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 Release(thr, pc, (uptr)new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 REAL(dispatch_group_notify_f)(group, q, new_context, dispatch_callback_wrap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 TSAN_INTERCEPTOR(void, dispatch_group_notify_f, dispatch_group_t group,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 dispatch_queue_t q, void *context, dispatch_function_t work) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 WRAP(dispatch_group_notify)(group, q, ^(void) { work(context); });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 TSAN_INTERCEPTOR(void, dispatch_source_set_event_handler,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 dispatch_source_t source, dispatch_block_t handler) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 SCOPED_TSAN_INTERCEPTOR(dispatch_source_set_event_handler, source, handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 if (handler == nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 return REAL(dispatch_source_set_event_handler)(source, nullptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 dispatch_queue_t q = GetTargetQueueFromSource(source);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 q, handler, &invoke_block, false, false, false, 0 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 dispatch_block_t new_handler = Block_copy(^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 new_context.orig_context = handler; // To explicitly capture "handler".
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 REAL(dispatch_source_set_event_handler)(source, new_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 Block_release(new_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 TSAN_INTERCEPTOR(void, dispatch_source_set_event_handler_f,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 dispatch_source_t source, dispatch_function_t handler) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 SCOPED_TSAN_INTERCEPTOR(dispatch_source_set_event_handler_f, source, handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 if (handler == nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 return REAL(dispatch_source_set_event_handler)(source, nullptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 dispatch_block_t block = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 handler(dispatch_get_context(source));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 WRAP(dispatch_source_set_event_handler)(source, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 TSAN_INTERCEPTOR(void, dispatch_source_set_cancel_handler,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 dispatch_source_t source, dispatch_block_t handler) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 SCOPED_TSAN_INTERCEPTOR(dispatch_source_set_cancel_handler, source, handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 if (handler == nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 return REAL(dispatch_source_set_cancel_handler)(source, nullptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 dispatch_queue_t q = GetTargetQueueFromSource(source);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 q, handler, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 dispatch_block_t new_handler = Block_copy(^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 new_context.orig_context = handler; // To explicitly capture "handler".
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 REAL(dispatch_source_set_cancel_handler)(source, new_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 Block_release(new_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 TSAN_INTERCEPTOR(void, dispatch_source_set_cancel_handler_f,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 dispatch_source_t source, dispatch_function_t handler) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 SCOPED_TSAN_INTERCEPTOR(dispatch_source_set_cancel_handler_f, source,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 if (handler == nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 return REAL(dispatch_source_set_cancel_handler)(source, nullptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 dispatch_block_t block = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 handler(dispatch_get_context(source));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 WRAP(dispatch_source_set_cancel_handler)(source, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 TSAN_INTERCEPTOR(void, dispatch_source_set_registration_handler,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 dispatch_source_t source, dispatch_block_t handler) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 SCOPED_TSAN_INTERCEPTOR(dispatch_source_set_registration_handler, source,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 if (handler == nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 return REAL(dispatch_source_set_registration_handler)(source, nullptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 dispatch_queue_t q = GetTargetQueueFromSource(source);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 q, handler, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 dispatch_block_t new_handler = Block_copy(^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 new_context.orig_context = handler; // To explicitly capture "handler".
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 REAL(dispatch_source_set_registration_handler)(source, new_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 Block_release(new_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 TSAN_INTERCEPTOR(void, dispatch_source_set_registration_handler_f,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 dispatch_source_t source, dispatch_function_t handler) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 SCOPED_TSAN_INTERCEPTOR(dispatch_source_set_registration_handler_f, source,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 if (handler == nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 return REAL(dispatch_source_set_registration_handler)(source, nullptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 dispatch_block_t block = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 handler(dispatch_get_context(source));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 WRAP(dispatch_source_set_registration_handler)(source, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 TSAN_INTERCEPTOR(void, dispatch_apply, size_t iterations,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 dispatch_queue_t queue,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 DISPATCH_NOESCAPE void (^block)(size_t)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 SCOPED_TSAN_INTERCEPTOR(dispatch_apply, iterations, queue, block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 u8 sync1, sync2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 uptr parent_to_child_sync = (uptr)&sync1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 uptr child_to_parent_sync = (uptr)&sync2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 Release(thr, pc, parent_to_child_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 void (^new_block)(size_t) = ^(size_t iteration) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 SCOPED_INTERCEPTOR_RAW(dispatch_apply);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 Acquire(thr, pc, parent_to_child_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 block(iteration);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 Release(thr, pc, child_to_parent_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 REAL(dispatch_apply)(iterations, queue, new_block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 Acquire(thr, pc, child_to_parent_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 static void invoke_block_iteration(void *param, size_t iteration) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 auto block = (void (^)(size_t)) param;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 block(iteration);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 TSAN_INTERCEPTOR(void, dispatch_apply_f, size_t iterations,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 dispatch_queue_t queue, void *context,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 void (*work)(void *, size_t)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 SCOPED_TSAN_INTERCEPTOR(dispatch_apply_f, iterations, queue, context, work);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 // Unfortunately, we cannot delegate to dispatch_apply, since libdispatch
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 // implements dispatch_apply in terms of dispatch_apply_f.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 u8 sync1, sync2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 uptr parent_to_child_sync = (uptr)&sync1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 uptr child_to_parent_sync = (uptr)&sync2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 Release(thr, pc, parent_to_child_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 void (^new_block)(size_t) = ^(size_t iteration) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 SCOPED_INTERCEPTOR_RAW(dispatch_apply_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 Acquire(thr, pc, parent_to_child_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 work(context, iteration);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 Release(thr, pc, child_to_parent_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 REAL(dispatch_apply_f)(iterations, queue, new_block, invoke_block_iteration);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 Acquire(thr, pc, child_to_parent_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 DECLARE_REAL_AND_INTERCEPTOR(int, munmap, void *addr, long_t sz)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 TSAN_INTERCEPTOR(dispatch_data_t, dispatch_data_create, const void *buffer,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 size_t size, dispatch_queue_t q, dispatch_block_t destructor) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 SCOPED_TSAN_INTERCEPTOR(dispatch_data_create, buffer, size, q, destructor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 if ((q == nullptr) || (destructor == DISPATCH_DATA_DESTRUCTOR_DEFAULT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 return REAL(dispatch_data_create)(buffer, size, q, destructor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 if (destructor == DISPATCH_DATA_DESTRUCTOR_FREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 destructor = ^(void) { WRAP(free)((void *)(uintptr_t)buffer); };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 else if (destructor == DISPATCH_DATA_DESTRUCTOR_MUNMAP)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 destructor = ^(void) { WRAP(munmap)((void *)(uintptr_t)buffer, size); };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 dispatch_block_t heap_block = Block_copy(destructor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 block_context_t *new_context =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 AllocContext(thr, pc, q, heap_block, &invoke_and_release_block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 uptr submit_sync = (uptr)new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 return REAL(dispatch_data_create)(buffer, size, q, ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 dispatch_callback_wrap(new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 typedef void (^fd_handler_t)(dispatch_data_t data, int error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 typedef void (^cleanup_handler_t)(int error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 TSAN_INTERCEPTOR(void, dispatch_read, dispatch_fd_t fd, size_t length,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 dispatch_queue_t q, fd_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 SCOPED_TSAN_INTERCEPTOR(dispatch_read, fd, length, q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 fd_handler_t new_h = Block_copy(^(dispatch_data_t data, int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 h(data, error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 REAL(dispatch_read)(fd, length, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 TSAN_INTERCEPTOR(void, dispatch_write, dispatch_fd_t fd, dispatch_data_t data,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 dispatch_queue_t q, fd_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 SCOPED_TSAN_INTERCEPTOR(dispatch_write, fd, data, q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 fd_handler_t new_h = Block_copy(^(dispatch_data_t data, int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 h(data, error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 REAL(dispatch_write)(fd, data, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 TSAN_INTERCEPTOR(void, dispatch_io_read, dispatch_io_t channel, off_t offset,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 size_t length, dispatch_queue_t q, dispatch_io_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 SCOPED_TSAN_INTERCEPTOR(dispatch_io_read, channel, offset, length, q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 dispatch_io_handler_t new_h =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 Block_copy(^(bool done, dispatch_data_t data, int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 h(done, data, error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 REAL(dispatch_io_read)(channel, offset, length, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 TSAN_INTERCEPTOR(void, dispatch_io_write, dispatch_io_t channel, off_t offset,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 dispatch_data_t data, dispatch_queue_t q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 dispatch_io_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 SCOPED_TSAN_INTERCEPTOR(dispatch_io_write, channel, offset, data, q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 dispatch_io_handler_t new_h =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 Block_copy(^(bool done, dispatch_data_t data, int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 h(done, data, error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 REAL(dispatch_io_write)(channel, offset, data, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 TSAN_INTERCEPTOR(void, dispatch_io_barrier, dispatch_io_t channel,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 dispatch_block_t barrier) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 SCOPED_TSAN_INTERCEPTOR(dispatch_io_barrier, channel, barrier);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 nullptr, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 new_context.non_queue_sync_object = (uptr)channel;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 new_context.is_barrier_block = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 dispatch_block_t new_block = Block_copy(^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 barrier();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 REAL(dispatch_io_barrier)(channel, new_block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 Block_release(new_block);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create, dispatch_io_type_t type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 dispatch_fd_t fd, dispatch_queue_t q, cleanup_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 SCOPED_TSAN_INTERCEPTOR(dispatch_io_create, type, fd, q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 __block dispatch_io_t new_channel = nullptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 cleanup_handler_t new_h = Block_copy(^(int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 SCOPED_INTERCEPTOR_RAW(dispatch_io_create_callback);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 Acquire(thr, pc, (uptr)new_channel); // Release() in dispatch_io_close.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 h(error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 new_channel = REAL(dispatch_io_create)(type, fd, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 return new_channel;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create_with_path,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 dispatch_io_type_t type, const char *path, int oflag,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 mode_t mode, dispatch_queue_t q, cleanup_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 SCOPED_TSAN_INTERCEPTOR(dispatch_io_create_with_path, type, path, oflag, mode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 __block dispatch_io_t new_channel = nullptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 cleanup_handler_t new_h = Block_copy(^(int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 SCOPED_INTERCEPTOR_RAW(dispatch_io_create_callback);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 Acquire(thr, pc, (uptr)new_channel); // Release() in dispatch_io_close.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 h(error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 new_channel =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 REAL(dispatch_io_create_with_path)(type, path, oflag, mode, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 return new_channel;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create_with_io,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 dispatch_io_type_t type, dispatch_io_t io, dispatch_queue_t q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 cleanup_handler_t h) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 SCOPED_TSAN_INTERCEPTOR(dispatch_io_create_with_io, type, io, q, h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 __block dispatch_io_t new_channel = nullptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 __block block_context_t new_context = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 q, nullptr, &invoke_block, false, false, false, 0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 cleanup_handler_t new_h = Block_copy(^(int error) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 SCOPED_INTERCEPTOR_RAW(dispatch_io_create_callback);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 Acquire(thr, pc, (uptr)new_channel); // Release() in dispatch_io_close.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 new_context.orig_context = ^(void) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 h(error);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 dispatch_callback_wrap(&new_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 uptr submit_sync = (uptr)&new_context;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 Release(thr, pc, submit_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 new_channel = REAL(dispatch_io_create_with_io)(type, io, q, new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 Block_release(new_h);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 return new_channel;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 TSAN_INTERCEPTOR(void, dispatch_io_close, dispatch_io_t channel,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 dispatch_io_close_flags_t flags) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 SCOPED_TSAN_INTERCEPTOR(dispatch_io_close, channel, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 Release(thr, pc, (uptr)channel); // Acquire() in dispatch_io_create[_*].
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 return REAL(dispatch_io_close)(channel, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 // Resuming a suspended queue needs to synchronize with all subsequent
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 // executions of blocks in that queue.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 TSAN_INTERCEPTOR(void, dispatch_resume, dispatch_object_t o) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 SCOPED_TSAN_INTERCEPTOR(dispatch_resume, o);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 Release(thr, pc, (uptr)o); // Synchronizes with the Acquire() on serial_sync
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 // in dispatch_sync_pre_execute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 return REAL(dispatch_resume)(o);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 void InitializeLibdispatchInterceptors() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 INTERCEPT_FUNCTION(dispatch_async);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 INTERCEPT_FUNCTION(dispatch_async_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 INTERCEPT_FUNCTION(dispatch_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 INTERCEPT_FUNCTION(dispatch_sync_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 INTERCEPT_FUNCTION(dispatch_barrier_async);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 INTERCEPT_FUNCTION(dispatch_barrier_async_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 INTERCEPT_FUNCTION(dispatch_barrier_sync);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 INTERCEPT_FUNCTION(dispatch_barrier_sync_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 INTERCEPT_FUNCTION(dispatch_after);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 INTERCEPT_FUNCTION(dispatch_after_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 INTERCEPT_FUNCTION(dispatch_once);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 INTERCEPT_FUNCTION(dispatch_once_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 INTERCEPT_FUNCTION(dispatch_semaphore_signal);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 INTERCEPT_FUNCTION(dispatch_semaphore_wait);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 INTERCEPT_FUNCTION(dispatch_group_wait);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 INTERCEPT_FUNCTION(dispatch_group_leave);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 INTERCEPT_FUNCTION(dispatch_group_async);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758 INTERCEPT_FUNCTION(dispatch_group_async_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 INTERCEPT_FUNCTION(dispatch_group_notify);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 INTERCEPT_FUNCTION(dispatch_group_notify_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 INTERCEPT_FUNCTION(dispatch_source_set_event_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 INTERCEPT_FUNCTION(dispatch_source_set_event_handler_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 INTERCEPT_FUNCTION(dispatch_source_set_cancel_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 INTERCEPT_FUNCTION(dispatch_source_set_cancel_handler_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 INTERCEPT_FUNCTION(dispatch_source_set_registration_handler);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 INTERCEPT_FUNCTION(dispatch_source_set_registration_handler_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 INTERCEPT_FUNCTION(dispatch_apply);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 INTERCEPT_FUNCTION(dispatch_apply_f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 INTERCEPT_FUNCTION(dispatch_data_create);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 INTERCEPT_FUNCTION(dispatch_read);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 INTERCEPT_FUNCTION(dispatch_write);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 INTERCEPT_FUNCTION(dispatch_io_read);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 INTERCEPT_FUNCTION(dispatch_io_write);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 INTERCEPT_FUNCTION(dispatch_io_barrier);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 INTERCEPT_FUNCTION(dispatch_io_create);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 INTERCEPT_FUNCTION(dispatch_io_create_with_path);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 INTERCEPT_FUNCTION(dispatch_io_create_with_io);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 INTERCEPT_FUNCTION(dispatch_io_close);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 INTERCEPT_FUNCTION(dispatch_resume);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 } // namespace __tsan