aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/private
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-09-19 12:56:37 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-19 18:05:50 +0000
commite395bf2d189e22822ddf2b46541c510d6d8fbcc0 (patch)
treedd3780a0b5b891e6b25b8b3237364ebba9f8d273 /include/private
parent7028443d1d70a2497f315443dfd45a157f300854 (diff)
Mac TSAN support: annotate Sk[Base]Mutex as a mutex.
TSAN does not intercept Mach semaphore_t calls used to implement SkBaseMutex's fSemaphore (its OSSemaphore field). We can teach it that Sk[Base]Mutex is a mutex anyway with the same annotations we use for SkSharedMutex. Change-Id: Ib91928bb9fcfa94f5cea985b46dea31ff2b56963 Reviewed-on: https://skia-review.googlesource.com/48580 Commit-Queue: Mike Klein <mtklein@chromium.org> Reviewed-by: Herb Derby <herb@google.com>
Diffstat (limited to 'include/private')
-rw-r--r--include/private/SkMutex.h14
-rw-r--r--include/private/SkTSAN.h76
2 files changed, 88 insertions, 2 deletions
diff --git a/include/private/SkMutex.h b/include/private/SkMutex.h
index 7cfdb1132c..da9a80b00e 100644
--- a/include/private/SkMutex.h
+++ b/include/private/SkMutex.h
@@ -10,10 +10,15 @@
#include "../private/SkSemaphore.h"
#include "../private/SkThreadID.h"
+#include "SkTSAN.h"
#include "SkTypes.h"
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name;
+// We use ANNOTE_RWLOCK_foo() macros in here because TSAN does
+// not intercept Mach semaphore_t calls, and so on Mac can't
+// see that SkMutex is indeed a mutex.
+
class SkBaseMutex {
public:
constexpr SkBaseMutex() = default;
@@ -21,10 +26,12 @@ public:
void acquire() {
fSemaphore.wait();
SkDEBUGCODE(fOwner = SkGetThreadID();)
+ ANNOTATE_RWLOCK_ACQUIRED(&fSemaphore, true);
}
void release() {
this->assertHeld();
+ ANNOTATE_RWLOCK_RELEASED(&fSemaphore, true);
SkDEBUGCODE(fOwner = kIllegalThreadID;)
fSemaphore.signal();
}
@@ -40,8 +47,11 @@ protected:
class SkMutex : public SkBaseMutex {
public:
- using SkBaseMutex::SkBaseMutex;
- ~SkMutex() { fSemaphore.cleanup(); }
+ SkMutex() { ANNOTATE_RWLOCK_CREATE(&fSemaphore); }
+ ~SkMutex() {
+ ANNOTATE_RWLOCK_DESTROY(&fSemaphore);
+ fSemaphore.cleanup();
+ }
};
class SkAutoMutexAcquire {
diff --git a/include/private/SkTSAN.h b/include/private/SkTSAN.h
new file mode 100644
index 0000000000..52f6bad4fe
--- /dev/null
+++ b/include/private/SkTSAN.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTSAN_DEFINED
+#define SkTSAN_DEFINED
+
+#include "SkTypes.h"
+
+#if !defined(__DYNAMIC_ANNOTATIONS_H__)
+
+ #if !defined(__has_feature)
+ #define __has_feature(x) 0
+ #endif
+
+ #if __has_feature(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)
+
+ #if defined(DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK)
+ #if defined(__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
+
+#endif//!defined(__DYNAMIC_ANNOTATIONS_H__)
+
+#endif//SkTSAN_DEFINED