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.
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.