Index: src/core/SkSharedMutex.h |
diff --git a/src/core/SkSharedMutex.h b/src/core/SkSharedMutex.h |
index f3430040e38b51ee05ddb9d2915db44a30ff6ec3..270316fa20b6377a0c2c998b02cf1f75d9fb8c47 100644 |
--- a/src/core/SkSharedMutex.h |
+++ b/src/core/SkSharedMutex.h |
@@ -11,13 +11,92 @@ |
#include "SkAtomics.h" |
#include "SkSemaphore.h" |
#include "SkTypes.h" |
- |
-// This is a shared lock implementation similar to pthreads rwlocks. This implementation is |
-// cribbed from Preshing's article: |
+ |
+// There are two shared lock implementations one debug the other is high performance. They implement |
+// an interface similar to pthread's rwlocks. |
+// This is a shared lock implementation similar to pthreads rwlocks. The high performance |
+// implementation is cribbed from Preshing's article: |
// http://preshing.com/20150316/semaphores-are-surprisingly-versatile/ |
// |
// This lock does not obey strict queue ordering. It will always alternate between readers and |
// a single writer. |
+ |
+#ifdef SK_DEBUG |
mtklein
2015/09/09 18:48:12
I generally think google3's style on not indenting
|
+#include "SkMutex.h" |
+#include "SkTDArray.h" |
+#ifdef SK_BUILD_FOR_WIN |
+#include <windows.h> |
+class SkThreadID { |
+public: |
+ SkThreadID() : fThreadID(GetCurrentThreadId()) { } |
+ bool operator==(const SkThreadID& that) const { |
+ return fThreadID == that.fThreadID; |
+ } |
+ |
+ int64_t toInt() const { |
+ return (int64_t)fThreadID; |
+ } |
+ |
+private: |
+ DWORD fThreadID; |
+}; |
+#else |
+#include <pthread.h> |
+class SkThreadID { |
mtklein
2015/09/09 18:48:12
Why don't we nest these inside SkSharedMutex as Th
|
+public: |
+ SkThreadID() : fThreadID(pthread_self()) { } |
+ bool operator==(const SkThreadID& that) const { |
+ return fThreadID == that.fThreadID; |
+ } |
+ int64_t toInt() const { |
+ return (int64_t)fThreadID; |
+ } |
+private: |
+ pthread_t fThreadID; |
+}; |
+#endif |
+ |
+class SkThreadIDSet { |
+public: |
+ // Returns true if threadID is in the set. |
+ bool Find(SkThreadID threadID) const { |
mtklein
2015/09/09 18:48:12
find, tryAdd, tryRemove, swap, count() :P
|
+ for (auto& t : fThreadIDs) { |
+ if (t == threadID) return true; |
+ } |
+ return false; |
+ } |
+ |
+ // Returns true if did not already exist. |
+ bool TryAdd(SkThreadID threadID) { |
+ for (auto& t : fThreadIDs) { |
+ if (t == threadID) return false; |
+ } |
+ fThreadIDs.append(1, &threadID); |
+ return true; |
+ } |
+ // Returns true if already exists in Set. |
+ bool TryRemove(SkThreadID threadID) { |
+ for (int i = 0; i < fThreadIDs.count(); ++i) { |
+ if (fThreadIDs[i] == threadID) { |
+ fThreadIDs.remove(i); |
+ return true; |
+ } |
+ } |
+ return false; |
+ } |
+ |
+ void Swap(SkThreadIDSet& other) { |
+ fThreadIDs.swap(other.fThreadIDs); |
+ } |
+ |
+ int Count() const { |
+ return fThreadIDs.count(); |
+ } |
+ |
+private: |
+ SkTDArray<SkThreadID> fThreadIDs; |
+}; |
+ |
class SkSharedMutex { |
public: |
SkSharedMutex(); |
@@ -29,11 +108,7 @@ public: |
void release(); |
// Fail if exclusive is not held. |
-#ifdef SK_DEBUG |
void assertHeld() const; |
-#else |
- void assertHeld() const {} |
-#endif |
// Acquire lock for shared use. |
void acquireShared(); |
@@ -42,11 +117,39 @@ public: |
void releaseShared(); |
// Fail if shared lock not held. |
-#ifdef SK_DEBUG |
void assertHeldShared() const; |
+ |
+private: |
+ SkThreadIDSet fCurrentShared; |
+ SkThreadIDSet fWaitingExclusive; |
+ SkThreadIDSet fWaitingShared; |
+ int fSharedQueueSelect{0}; |
+ mutable SkMutex fMu; |
+ SkSemaphore fSharedQueue[2]; |
+ SkSemaphore fExclusiveQueue; |
+}; |
#else |
+class SkSharedMutex { |
+public: |
+ SkSharedMutex(); |
+ ~SkSharedMutex(); |
+ // Acquire lock for exclusive use. |
+ void acquire(); |
+ |
+ // Release lock for exclusive use. |
+ void release(); |
+ |
+ // Fail if exclusive is not held. |
+ void assertHeld() const {} |
+ |
+ // Acquire lock for shared use. |
+ void acquireShared(); |
+ |
+ // Release lock for shared use. |
+ void releaseShared(); |
+ |
+ // Fail if shared lock not held. |
void assertHeldShared() const {} |
-#endif |
private: |
SkAtomic<int32_t> fQueueCounts; |
mtklein
2015/09/09 18:48:11
I think I'd feel more cozy if there really were ju
|
@@ -54,5 +157,7 @@ private: |
SkSemaphore fExclusiveQueue; |
}; |
+#endif // SK_DEBUG |
+ |
#endif // SkSharedLock_DEFINED |