Switch SkSemaphore to use dispatch_semaphore_t on Mac.

The dispatch_semaphore_t is a higher-level, more-efficient semaphore
primitive if the cross-process capabilities of semaphore_t are not
needed.

Bug: chromium:1012386
Change-Id: I7c39fa6b8c015bdf7b4b2275da8165165253c2d1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248259
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Robert Sesek 2019-10-11 16:58:01 -04:00 committed by Skia Commit-Bot
parent a4b5228e16
commit caf025e8f5

View File

@ -9,10 +9,10 @@
#include "src/core/SkLeanWindows.h"
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
#include <mach/mach.h>
#include <dispatch/dispatch.h>
// We've got to teach TSAN that there is a happens-before edge between
// semaphore_signal() and semaphore_wait().
// dispatch_semaphore_signal() and dispatch_semaphore_wait().
#if __has_feature(thread_sanitizer)
extern "C" void AnnotateHappensBefore(const char*, int, void*);
extern "C" void AnnotateHappensAfter (const char*, int, void*);
@ -22,28 +22,22 @@
#endif
struct SkSemaphore::OSSemaphore {
semaphore_t fSemaphore;
dispatch_semaphore_t fSemaphore;
OSSemaphore() {
semaphore_create(mach_task_self(), &fSemaphore, SYNC_POLICY_LIFO, 0/*initial count*/);
fSemaphore = dispatch_semaphore_create(0/*initial count*/);
}
~OSSemaphore() { semaphore_destroy(mach_task_self(), fSemaphore); }
~OSSemaphore() { dispatch_release(fSemaphore); }
void signal(int n) {
while (n --> 0) {
while (n-- > 0) {
AnnotateHappensBefore(__FILE__, __LINE__, &fSemaphore);
semaphore_signal(fSemaphore);
dispatch_semaphore_signal(fSemaphore);
}
}
void wait() {
while (true) {
kern_return_t result = semaphore_wait(fSemaphore);
if (result == KERN_SUCCESS) {
AnnotateHappensAfter(__FILE__, __LINE__, &fSemaphore);
return;
}
SkASSERT(result == KERN_ABORTED);
}
dispatch_semaphore_wait(fSemaphore, DISPATCH_TIME_FOREVER);
AnnotateHappensAfter(__FILE__, __LINE__, &fSemaphore);
}
};
#elif defined(SK_BUILD_FOR_WIN)