diff options
author | Mike Klein <mtklein@chromium.org> | 2017-09-20 09:53:39 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-09-21 17:09:40 +0000 |
commit | 3b7658a4752e1332c684ad757686ce9ee0e5fbd1 (patch) | |
tree | dff539a1555c58e2bb9ea34c288acfc978906d35 /src/core | |
parent | f50f4a4c55ed4dea457d48010690bbe3f3c69530 (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.cpp | 23 | ||||
-rw-r--r-- | src/core/SkSharedMutex.cpp | 60 |
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" |