Chromium Code Reviews| Index: src/core/SkSharedMutex.h |
| diff --git a/src/core/SkSharedMutex.h b/src/core/SkSharedMutex.h |
| index f3430040e38b51ee05ddb9d2915db44a30ff6ec3..358f4960a7a38fad00850cca16bba36e4b6f6700 100644 |
| --- a/src/core/SkSharedMutex.h |
| +++ b/src/core/SkSharedMutex.h |
| @@ -11,9 +11,25 @@ |
| #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: |
| + |
| +#ifdef SK_DEBUG |
| + #include "SkMutex.h" |
| + #include "SkTDArray.h" |
| + #ifdef SK_BUILD_FOR_WIN |
| + #include <windows.h> |
| + typedef DWORD threadID_t; |
| + static threadID_t getThreadID() { return GetCurrentThreadId(); } |
|
mtklein_C
2015/09/17 19:51:42
These standalone statics are typically get_thread_
herb_g
2015/09/17 21:39:41
Done.
|
| + #else |
| + #include <pthread.h> |
| + typedef pthread_t threadID_t; |
| + static threadID_t getThreadID() { return pthread_self(); } |
|
mtklein_C
2015/09/17 19:51:42
static int64_t get_thread_id() { return (int64_t)p
herb_g
2015/09/17 21:39:41
Done.
|
| + #endif |
| +#endif // SK_DEBUG |
| + |
| +// 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 |
| @@ -29,11 +45,7 @@ public: |
| void release(); |
| // Fail if exclusive is not held. |
| -#ifdef SK_DEBUG |
| void assertHeld() const; |
|
mtklein_C
2015/09/17 19:51:42
undo these bits?
herb_g
2015/09/17 21:39:41
Done.
|
| -#else |
| - void assertHeld() const {} |
| -#endif |
| // Acquire lock for shared use. |
| void acquireShared(); |
| @@ -42,17 +54,72 @@ public: |
| void releaseShared(); |
| // Fail if shared lock not held. |
| -#ifdef SK_DEBUG |
| void assertHeldShared() const; |
| -#else |
| - void assertHeldShared() const {} |
| -#endif |
| private: |
| +#ifdef SK_DEBUG |
| + class ThreadID { |
| + public: |
| + ThreadID() : fThreadID(getThreadID()) { } |
| + bool operator==(const ThreadID& that) const { return fThreadID == that.fThreadID; } |
| + int64_t toInt() const { return (int64_t)fThreadID; } |
| + private: |
| + threadID_t fThreadID; |
| + }; |
| + |
| + class ThreadIDSet { |
| + public: |
| + // Returns true if threadID is in the set. |
| + bool find(ThreadID threadID) const { |
| + for (auto& t : fThreadIDs) { |
| + if (t == threadID) return true; |
| + } |
| + return false; |
| + } |
| + |
| + // Returns true if did not already exist. |
| + bool tryAdd(ThreadID 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(ThreadID threadID) { |
| + for (int i = 0; i < fThreadIDs.count(); ++i) { |
| + if (fThreadIDs[i] == threadID) { |
| + fThreadIDs.remove(i); |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + void swap(ThreadIDSet& other) { |
| + fThreadIDs.swap(other.fThreadIDs); |
| + } |
| + |
| + int count() const { |
| + return fThreadIDs.count(); |
| + } |
| + |
| + private: |
| + SkTDArray<ThreadID> fThreadIDs; |
| + }; |
| + |
| + ThreadIDSet fCurrentShared; |
| + ThreadIDSet fWaitingExclusive; |
| + ThreadIDSet fWaitingShared; |
| + int fSharedQueueSelect{0}; |
| + mutable SkMutex fMu; |
| + SkSemaphore fSharedQueue[2]; |
| + SkSemaphore fExclusiveQueue; |
| +#else |
| SkAtomic<int32_t> fQueueCounts; |
| - SkSemaphore fSharedQueue; |
| - SkSemaphore fExclusiveQueue; |
| + SkSemaphore fSharedQueue; |
| + SkSemaphore fExclusiveQueue; |
| +#endif // SK_DEBUG |
| }; |
| - |
| #endif // SkSharedLock_DEFINED |