diff options
-rw-r--r-- | src/core/SkSharedMutex.cpp | 30 | ||||
-rw-r--r-- | src/core/SkSharedMutex.h | 15 | ||||
-rw-r--r-- | tests/SkSharedMutexTest.cpp | 4 |
3 files changed, 49 insertions, 0 deletions
diff --git a/src/core/SkSharedMutex.cpp b/src/core/SkSharedMutex.cpp index b9af10a2be..4cf6312067 100644 --- a/src/core/SkSharedMutex.cpp +++ b/src/core/SkSharedMutex.cpp @@ -141,6 +141,23 @@ void SkSharedMutex::release() { } } +#ifdef SK_DEBUG +void SkSharedMutex::assertHeld() const { + int32_t queueCounts = fQueueCounts.load(sk_memory_order_relaxed); + // These are very loose asserts about the mutex being held exclusively. + SkASSERTF(0 == (queueCounts & kSharedMask), + "running shared: %d, exclusive: %d, waiting shared: %d", + (queueCounts & kSharedMask) >> kSharedOffset, + (queueCounts & kWaitingExclusiveMask) >> kWaitingExlusiveOffset, + (queueCounts & kWaitingSharedMask) >> kWaitingSharedOffset); + SkASSERTF((queueCounts & kWaitingExclusiveMask) > 0, + "running shared: %d, exclusive: %d, waiting shared: %d", + (queueCounts & kSharedMask) >> kSharedOffset, + (queueCounts & kWaitingExclusiveMask) >> kWaitingExlusiveOffset, + (queueCounts & kWaitingSharedMask) >> kWaitingSharedOffset); +} +#endif + void SkSharedMutex::acquireShared() { int32_t oldQueueCounts = fQueueCounts.load(sk_memory_order_relaxed); int32_t newQueueCounts; @@ -177,3 +194,16 @@ void SkSharedMutex::releaseShared() { fExclusiveQueue.signal(); } } + +#ifdef SK_DEBUG +void SkSharedMutex::assertHeldShared() const { + int32_t queueCounts = fQueueCounts.load(sk_memory_order_relaxed); + // A very loose assert about the mutex being shared. + SkASSERTF((queueCounts & kSharedMask) > 0, + "running shared: %d, exclusive: %d, waiting shared: %d", + (queueCounts & kSharedMask) >> kSharedOffset, + (queueCounts & kWaitingExclusiveMask) >> kWaitingExlusiveOffset, + (queueCounts & kWaitingSharedMask) >> kWaitingSharedOffset); +} + +#endif diff --git a/src/core/SkSharedMutex.h b/src/core/SkSharedMutex.h index a3535dca43..f3430040e3 100644 --- a/src/core/SkSharedMutex.h +++ b/src/core/SkSharedMutex.h @@ -28,16 +28,31 @@ public: // Release lock for exclusive use. 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(); // Release lock for shared use. void releaseShared(); + // Fail if shared lock not held. +#ifdef SK_DEBUG + void assertHeldShared() const; +#else + void assertHeldShared() const {} +#endif + private: SkAtomic<int32_t> fQueueCounts; SkSemaphore fSharedQueue; SkSemaphore fExclusiveQueue; }; + #endif // SkSharedLock_DEFINED diff --git a/tests/SkSharedMutexTest.cpp b/tests/SkSharedMutexTest.cpp index 49f01abfe4..bdf072b6b7 100644 --- a/tests/SkSharedMutexTest.cpp +++ b/tests/SkSharedMutexTest.cpp @@ -13,8 +13,10 @@ DEF_TEST(SkSharedMutexBasic, r) { SkSharedMutex sm; sm.acquire(); + sm.assertHeld(); sm.release(); sm.acquireShared(); + sm.assertHeldShared(); sm.releaseShared(); } @@ -30,6 +32,7 @@ DEF_TEST(SkSharedMutexMultiThreaded, r) { if (threadIndex % 4 != 0) { for (int c = 0; c < 100000; ++c) { sm.acquireShared(); + sm.assertHeldShared(); int v = shared[0]; for (int i = 1; i < kSharedSize; ++i) { REPORTER_ASSERT(r, v == shared[i]); @@ -39,6 +42,7 @@ DEF_TEST(SkSharedMutexMultiThreaded, r) { } else { for (int c = 0; c < 100000; ++c) { sm.acquire(); + sm.assertHeld(); value += 1; for (int i = 0; i < kSharedSize; ++i) { shared[i] = value; |