aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/private/SkMutex.h14
-rw-r--r--include/private/SkTSAN.h76
-rw-r--r--src/core/SkSemaphore.cpp23
-rw-r--r--src/core/SkSharedMutex.cpp60
4 files changed, 82 insertions, 91 deletions
diff --git a/include/private/SkMutex.h b/include/private/SkMutex.h
index da9a80b00e..7cfdb1132c 100644
--- a/include/private/SkMutex.h
+++ b/include/private/SkMutex.h
@@ -10,15 +10,10 @@
#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;
@@ -26,12 +21,10 @@ 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();
}
@@ -47,11 +40,8 @@ protected:
class SkMutex : public SkBaseMutex {
public:
- SkMutex() { ANNOTATE_RWLOCK_CREATE(&fSemaphore); }
- ~SkMutex() {
- ANNOTATE_RWLOCK_DESTROY(&fSemaphore);
- fSemaphore.cleanup();
- }
+ using SkBaseMutex::SkBaseMutex;
+ ~SkMutex() { fSemaphore.cleanup(); }
};
class SkAutoMutexAcquire {
diff --git a/include/private/SkTSAN.h b/include/private/SkTSAN.h
deleted file mode 100644
index 52f6bad4fe..0000000000
--- a/include/private/SkTSAN.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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
diff --git a/src/core/SkSemaphore.cpp b/src/core/SkSemaphore.cpp
index f8f6e165ad..6ad10c4317 100644
--- a/src/core/SkSemaphore.cpp
+++ b/src/core/SkSemaphore.cpp
@@ -10,6 +10,17 @@
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
#include <mach/mach.h>
+
+ // We've got to teach TSAN that there is a happens-before edge beteween
+ // semaphore_signal() and semaphore_wait().
+ #if __has_feature(thread_sanitizer)
+ extern "C" void AnnotateHappensBefore(const char*, int, void*);
+ extern "C" void AnnotateHappensAfter (const char*, int, void*);
+ #else
+ static void AnnotateHappensBefore(const char*, int, void*) {}
+ static void AnnotateHappensAfter (const char*, int, void*) {}
+ #endif
+
struct SkBaseSemaphore::OSSemaphore {
semaphore_t fSemaphore;
@@ -18,8 +29,16 @@
}
~OSSemaphore() { semaphore_destroy(mach_task_self(), fSemaphore); }
- void signal(int n) { while (n --> 0) { semaphore_signal(fSemaphore); } }
- void wait() { semaphore_wait(fSemaphore); }
+ void signal(int n) {
+ while (n --> 0) {
+ AnnotateHappensBefore(__FILE__, __LINE__, &fSemaphore);
+ semaphore_signal(fSemaphore);
+ }
+ }
+ void wait() {
+ semaphore_wait(fSemaphore);
+ AnnotateHappensAfter(__FILE__, __LINE__, &fSemaphore);
+ }
};
#elif defined(SK_BUILD_FOR_WIN32)
struct SkBaseSemaphore::OSSemaphore {
diff --git a/src/core/SkSharedMutex.cpp b/src/core/SkSharedMutex.cpp
index 8d6738f9e4..17714a7185 100644
--- a/src/core/SkSharedMutex.cpp
+++ b/src/core/SkSharedMutex.cpp
@@ -8,10 +8,68 @@
#include "SkSharedMutex.h"
#include "SkAtomics.h"
-#include "SkTSAN.h"
#include "SkTypes.h"
#include "SkSemaphore.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
+
#ifdef SK_DEBUG
#include "SkThreadID.h"