[TSan][libdispatch] Add interceptors for dispatch_async_and_wait()

Authored by yln on Aug 11 2020, 3:01 PM.


[TSan][libdispatch] Add interceptors for dispatch_async_and_wait()

Add interceptors for dispatch_async_and_wait[_f]() which was added in
macOS 10.14. This pair of functions is similar to dispatch_sync(),
but does not force a context switch of the queue onto the caller thread
when the queue is active (and hence is more efficient). For TSan, we
can apply the same semantics as for dispatch_sync().

From the header docs:

Differences with dispatch_sync()

When the runtime has brought up a thread to invoke the asynchronous
workitems already submitted to the specified queue, that servicing
thread will also be used to execute synchronous work submitted to the
queue with dispatch_async_and_wait().

However, if the runtime has not brought up a thread to service the
specified queue (because it has no workitems enqueued, or only
synchronous workitems), then dispatch_async_and_wait() will invoke the
workitem on the calling thread, similar to the behaviour of functions
in the dispatch_sync family.

Additional context:

The guidance is to use dispatch_async_and_wait() instead of
dispatch_sync() when it is necessary to mix async and sync calls on
the same queue. dispatch_async_and_wait() does not guarantee
execution on the caller thread which allows to reduce context switches
when the target queue is active.


Reviewed By: kubamracek

Differential Revision: https://reviews.llvm.org/D85854