aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-09-20 09:53:39 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-21 17:09:40 +0000
commit3b7658a4752e1332c684ad757686ce9ee0e5fbd1 (patch)
treedff539a1555c58e2bb9ea34c288acfc978906d35 /src/core
parentf50f4a4c55ed4dea457d48010690bbe3f3c69530 (diff)
Teach TSAN directly about semaphore_t.
Instead of teaching TSAN than SkMutex is a lock to get around it not understanding Mach semaphore_t routines, teach it that there is a happens-before relationship between semaphore_signal() and semaphore_wait(). This reverts commit e395bf2d189e22822ddf2b46541c510d6d8fbcc0. New changes are entirely restricted to SkSemaphore.cpp. Change-Id: I27f647b93c48e81e8327db849881d669c4cd3d04 Reviewed-on: https://skia-review.googlesource.com/49180 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkSemaphore.cpp23
-rw-r--r--src/core/SkSharedMutex.cpp60
2 files changed, 80 insertions, 3 deletions
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"