aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkSharedMutex.cpp30
-rw-r--r--src/core/SkSharedMutex.h15
-rw-r--r--tests/SkSharedMutexTest.cpp4
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;