Index: include/private/SkSemaphore.h |
diff --git a/src/core/SkSemaphore.h b/include/private/SkSemaphore.h |
similarity index 62% |
rename from src/core/SkSemaphore.h |
rename to include/private/SkSemaphore.h |
index 5f4c2968a77aed4a061c2b8e4347bc7567d20813..b5b5ea5957bbc14ad070a1735e5f412aec6b66db 100644 |
--- a/src/core/SkSemaphore.h |
+++ b/include/private/SkSemaphore.h |
@@ -10,6 +10,53 @@ |
#include "SkTypes.h" |
#include "SkAtomics.h" |
+#include "../private/SkOncePtr.h" |
+ |
+struct SkBaseSemaphore { |
+ |
+ // Increment the counter by 1. |
+ // This is a specialization for supporting SkMutex. |
+ void signal() { |
+ // Since this fetches the value before the add, 0 indicates that this thread is running and |
+ // no threads are waiting, -1 and below means that threads are waiting, but only signal 1 |
+ // thread to run. |
+ if (sk_atomic_fetch_add(&fCount, 1, sk_memory_order_release) < 0) { |
+ this->osSignal(1); |
+ } |
+ } |
+ |
+ // Increment the counter N times. |
+ // Generally it's better to call signal(N) instead of signal() N times. |
+ void signal(int N); |
+ |
+ // Decrement the counter by 1, |
+ // then if the counter is <= 0, sleep this thread until the counter is > 0. |
+ void wait() { |
+ // Since this fetches the value before the subtract, zero and below means that there are no |
+ // resources left, so the thread needs to wait. |
+ if (sk_atomic_fetch_sub(&fCount, 1, sk_memory_order_acquire) <= 0) { |
+ this->osWait(); |
+ } |
+ } |
+ |
+ struct OSSemaphore; |
+ |
+ void osSignal(int n); |
+ void osWait(); |
+ void deleteSemaphore(); |
+ |
+ // This implementation follows the general strategy of |
+ // 'A Lightweight Semaphore with Partial Spinning' |
+ // found here |
+ // http://preshing.com/20150316/semaphores-are-surprisingly-versatile/ |
+ // That article (and entire blog) are very much worth reading. |
+ // |
+ // We wrap an OS-provided semaphore with a user-space atomic counter that |
+ // lets us avoid interacting with the OS semaphore unless strictly required: |
+ // moving the count from >0 to <=0 or vice-versa, i.e. sleeping or waking threads. |
+ int fCount; |
+ SkBaseOncePtr<OSSemaphore> fOSSemaphore; |
+}; |
/** |
* SkSemaphore is a fast mostly-user-space semaphore. |
@@ -28,28 +75,12 @@ public: |
SkSemaphore(); |
~SkSemaphore(); |
- // Increment the counter N times. |
- // Generally it's better to call signal(N) instead of signal() N times. |
- void signal(int N = 1); |
- |
- // Decrement the counter by 1, |
- // then if the counter is <= 0, sleep this thread until the counter is > 0. |
void wait(); |
-private: |
- // This implementation follows the general strategy of |
- // 'A Lightweight Semaphore with Partial Spinning' |
- // found here |
- // http://preshing.com/20150316/semaphores-are-surprisingly-versatile/ |
- // That article (and entire blog) are very much worth reading. |
- // |
- // We wrap an OS-provided semaphore with a user-space atomic counter that |
- // lets us avoid interacting with the OS semaphore unless strictly required: |
- // moving the count from >0 to <=0 or vice-versa, i.e. sleeping or waking threads. |
- struct OSSemaphore; |
+ void signal(int n = 1); |
- SkAtomic<int> fCount; |
- OSSemaphore* fOSSemaphore; |
+private: |
+ SkBaseSemaphore fBaseSemaphore; |
}; |
#endif//SkSemaphore_DEFINED |