Index: src/core/SkSharedMutex.cpp |
diff --git a/src/core/SkSharedMutex.cpp b/src/core/SkSharedMutex.cpp |
index 5465e487f6a93fb9d13eacc83268963f4dc9d861..3815ec3f2805162e165e744396313e0f15e19016 100644 |
--- a/src/core/SkSharedMutex.cpp |
+++ b/src/core/SkSharedMutex.cpp |
@@ -11,6 +11,62 @@ |
#include "SkSemaphore.h" |
#include "SkTypes.h" |
+ |
+#if defined(THREAD_SANITIZER) |
+ |
+/* Report that a lock has been created at address "lock". */ |
+#define ANNOTATE_RWLOCK_CREATE(lock) \ |
+ AnnotateRWLockCreate(__FILE__, __LINE__, lock) |
+ |
+/* Report that the lock at address "lock" is about to be destroyed. */ |
+#define ANNOTATE_RWLOCK_DESTROY(lock) \ |
+ AnnotateRWLockDestroy(__FILE__, __LINE__, lock) |
+ |
+/* Report that the lock at address "lock" has been acquired. |
+ is_w=1 for writer lock, is_w=0 for reader lock. */ |
+#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ |
+ AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) |
+ |
+/* Report that the lock at address "lock" is about to be released. */ |
+#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ |
+ AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) |
+ |
+#ifdef DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK |
+# ifdef __GNUC__ |
+# define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK __attribute__((weak)) |
+# else |
+/* TODO(glider): for Windows support we may want to change this macro in order |
+ to prepend __declspec(selectany) to the annotations' declarations. */ |
+# error weak annotations are not supported for your compiler |
+# endif |
+#else |
+# define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK |
+#endif |
+ |
+extern "C" { |
+void AnnotateRWLockCreate( |
+ const char *file, int line, |
+ const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
+void AnnotateRWLockDestroy( |
+ const char *file, int line, |
+ const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
+void AnnotateRWLockAcquired( |
+ const char *file, int line, |
+ const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
+void AnnotateRWLockReleased( |
+ const char *file, int line, |
+ const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; |
+} |
+ |
+#else |
+ |
+#define ANNOTATE_RWLOCK_CREATE(lock) |
+#define ANNOTATE_RWLOCK_DESTROY(lock) |
+#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) |
+#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) |
+ |
+#endif |
+ |
// The fQueueCounts fields holds many counts in an int32_t in order to make managing them atomic. |
// These three counts must be the same size, so each gets 10 bits. The 10 bits represent |
// the log of the count which is 1024. |
@@ -31,8 +87,8 @@ enum { |
kWaitingSharedMask = ((1 << kLogThreadCount) - 1) << kWaitingSharedOffset, |
}; |
-SkSharedMutex::SkSharedMutex() : fQueueCounts(0) { } |
- |
+SkSharedMutex::SkSharedMutex() : fQueueCounts(0) { ANNOTATE_RWLOCK_CREATE(this); } |
+SkSharedMutex::~SkSharedMutex() { ANNOTATE_RWLOCK_DESTROY(this); } |
void SkSharedMutex::acquire() { |
// Increment the count of exclusive queue waiters. |
int32_t oldQueueCounts = fQueueCounts.fetch_add(1 << kWaitingExlusiveOffset, |
@@ -43,9 +99,12 @@ void SkSharedMutex::acquire() { |
if ((oldQueueCounts & kWaitingExclusiveMask) > 0 || (oldQueueCounts & kSharedMask) > 0) { |
fExclusiveQueue.wait(); |
} |
+ ANNOTATE_RWLOCK_ACQUIRED(this, 1); |
} |
void SkSharedMutex::release() { |
+ ANNOTATE_RWLOCK_RELEASED(this, 1); |
+ |
int32_t oldQueueCounts = fQueueCounts.load(sk_memory_order_relaxed); |
int32_t waitingShared; |
int32_t newQueueCounts; |
@@ -101,9 +160,13 @@ void SkSharedMutex::acquireShared() { |
if ((newQueueCounts & kWaitingExclusiveMask) > 0) { |
fSharedQueue.wait(); |
} |
+ ANNOTATE_RWLOCK_ACQUIRED(this, 0); |
+ |
} |
void SkSharedMutex::releaseShared() { |
+ ANNOTATE_RWLOCK_RELEASED(this, 0); |
+ |
// Decrement the shared count. |
int32_t oldQueueCounts = fQueueCounts.fetch_add(-1 << kSharedOffset, |
sk_memory_order_release); |