Index: src/core/SkSemaphore.h |
diff --git a/src/core/SkSemaphore.h b/src/core/SkSemaphore.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5f4c2968a77aed4a061c2b8e4347bc7567d20813 |
--- /dev/null |
+++ b/src/core/SkSemaphore.h |
@@ -0,0 +1,55 @@ |
+/* |
+ * Copyright 2015 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#ifndef SkSemaphore_DEFINED |
+#define SkSemaphore_DEFINED |
+ |
+#include "SkTypes.h" |
+#include "SkAtomics.h" |
+ |
+/** |
+ * SkSemaphore is a fast mostly-user-space semaphore. |
+ * |
+ * A semaphore is logically an atomic integer with a few special properties: |
+ * - The integer always starts at 0. |
+ * - You can only increment or decrement it, never read or write it. |
+ * - Increment is spelled 'signal()'; decrement is spelled 'wait()'. |
+ * - If a call to wait() decrements the counter to <= 0, |
+ * the calling thread sleeps until another thread signal()s it back above 0. |
+ */ |
+class SkSemaphore : SkNoncopyable { |
+public: |
+ // Initializes the counter to 0. |
+ // (Though all current implementations could start from an arbitrary value.) |
+ 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; |
+ |
+ SkAtomic<int> fCount; |
+ OSSemaphore* fOSSemaphore; |
+}; |
+ |
+#endif//SkSemaphore_DEFINED |