From 3b7658a4752e1332c684ad757686ce9ee0e5fbd1 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Wed, 20 Sep 2017 09:53:39 -0400 Subject: 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 Commit-Queue: Mike Klein --- src/core/SkSemaphore.cpp | 23 ++++++++++++++++-- src/core/SkSharedMutex.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) (limited to 'src/core') 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 + + // 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" -- cgit v1.2.3