forked from OSchip/llvm-project
[TSan][Linux] Fix libdispatch interception macros compilation errors
Most libdispatch functions come in two variants: callbacks can be specified via blocks or function pointers. Some of our interceptors for the block variant actually forward to the function variant. However, on Linux, `DECLARE_REAL(name)` has to appear before `REAL(name)`. This patch reorders _f variant interceptors before _b variants where possible and forward declares the _f variant in the remaining cases (cyclic dependency between _f and _b interceptors). Also rename macro to DISPATCH_INTERCEPT_ASYNC_F for better consistency. Reviewed By: dvyukov Differential Revision: https://reviews.llvm.org/D59067 llvm-svn: 355619
This commit is contained in:
parent
9ee68ffffd
commit
011a90b96a
|
@ -162,7 +162,7 @@ static void invoke_and_release_block(void *param) {
|
|||
Block_release(block);
|
||||
}
|
||||
|
||||
#define DISPATCH_INTERCEPT_B(name, barrier) \
|
||||
#define DISPATCH_INTERCEPT_ASYNC_B(name, barrier) \
|
||||
TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, dispatch_block_t block) { \
|
||||
SCOPED_TSAN_INTERCEPTOR(name, q, block); \
|
||||
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
|
||||
|
@ -190,7 +190,7 @@ static void invoke_and_release_block(void *param) {
|
|||
Acquire(thr, pc, (uptr)&new_context); \
|
||||
}
|
||||
|
||||
#define DISPATCH_INTERCEPT_F(name, barrier) \
|
||||
#define DISPATCH_INTERCEPT_ASYNC_F(name, barrier) \
|
||||
TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \
|
||||
dispatch_function_t work) { \
|
||||
SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \
|
||||
|
@ -216,18 +216,21 @@ static void invoke_and_release_block(void *param) {
|
|||
Acquire(thr, pc, (uptr)&new_context); \
|
||||
}
|
||||
|
||||
#define DISPATCH_INTERCEPT(name, barrier) \
|
||||
DISPATCH_INTERCEPT_ASYNC_F(name##_async_f, barrier) \
|
||||
DISPATCH_INTERCEPT_ASYNC_B(name##_async, barrier) \
|
||||
DISPATCH_INTERCEPT_SYNC_F(name##_sync_f, barrier) \
|
||||
DISPATCH_INTERCEPT_SYNC_B(name##_sync, barrier)
|
||||
|
||||
// We wrap dispatch_async, dispatch_sync and friends where we allocate a new
|
||||
// context, which is used to synchronize (we release the context before
|
||||
// submitting, and the callback acquires it before executing the original
|
||||
// callback).
|
||||
DISPATCH_INTERCEPT_B(dispatch_async, false)
|
||||
DISPATCH_INTERCEPT_B(dispatch_barrier_async, true)
|
||||
DISPATCH_INTERCEPT_F(dispatch_async_f, false)
|
||||
DISPATCH_INTERCEPT_F(dispatch_barrier_async_f, true)
|
||||
DISPATCH_INTERCEPT_SYNC_B(dispatch_sync, false)
|
||||
DISPATCH_INTERCEPT_SYNC_B(dispatch_barrier_sync, true)
|
||||
DISPATCH_INTERCEPT_SYNC_F(dispatch_sync_f, false)
|
||||
DISPATCH_INTERCEPT_SYNC_F(dispatch_barrier_sync_f, true)
|
||||
DISPATCH_INTERCEPT(dispatch, false)
|
||||
DISPATCH_INTERCEPT(dispatch_barrier, true)
|
||||
|
||||
DECLARE_REAL(void, dispatch_after_f, dispatch_time_t when,
|
||||
dispatch_queue_t queue, void *context, dispatch_function_t work)
|
||||
|
||||
TSAN_INTERCEPTOR(void, dispatch_after, dispatch_time_t when,
|
||||
dispatch_queue_t queue, dispatch_block_t block) {
|
||||
|
@ -354,6 +357,9 @@ TSAN_INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,
|
|||
});
|
||||
}
|
||||
|
||||
DECLARE_REAL(void, dispatch_group_notify_f, dispatch_group_t group,
|
||||
dispatch_queue_t q, void *context, dispatch_function_t work)
|
||||
|
||||
TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group,
|
||||
dispatch_queue_t q, dispatch_block_t block) {
|
||||
SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block);
|
||||
|
|
Loading…
Reference in New Issue