diff options
-rw-r--r-- | include/private/SkMutex.h | 14 | ||||
-rw-r--r-- | include/private/SkTSAN.h | 76 | ||||
-rw-r--r-- | src/core/SkSemaphore.cpp | 23 | ||||
-rw-r--r-- | src/core/SkSharedMutex.cpp | 60 |
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" |