Add asserts for shared mutex.

BUG=skia:

Review URL: https://codereview.chromium.org/1285973003
diff --git a/src/core/SkSharedMutex.cpp b/src/core/SkSharedMutex.cpp
index b9af10a..4cf6312 100644
--- a/src/core/SkSharedMutex.cpp
+++ b/src/core/SkSharedMutex.cpp
@@ -141,6 +141,23 @@
     }
 }
 
+#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 @@
         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 a3535dc..f343004 100644
--- a/src/core/SkSharedMutex.h
+++ b/src/core/SkSharedMutex.h
@@ -28,16 +28,31 @@
     // 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 49f01ab..bdf072b 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 @@
         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 @@
         } else {
             for (int c = 0; c < 100000; ++c) {
                 sm.acquire();
+                sm.assertHeld();
                 value += 1;
                 for (int i = 0; i < kSharedSize; ++i) {
                     shared[i] = value;