diff options
Diffstat (limited to 'src')
-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" |