diff options
author | 2017-09-19 12:56:37 -0400 | |
---|---|---|
committer | 2017-09-19 18:05:50 +0000 | |
commit | e395bf2d189e22822ddf2b46541c510d6d8fbcc0 (patch) | |
tree | dd3780a0b5b891e6b25b8b3237364ebba9f8d273 /include/private | |
parent | 7028443d1d70a2497f315443dfd45a157f300854 (diff) |
Mac TSAN support: annotate Sk[Base]Mutex as a mutex.
TSAN does not intercept Mach semaphore_t calls used to implement
SkBaseMutex's fSemaphore (its OSSemaphore field). We can teach
it that Sk[Base]Mutex is a mutex anyway with the same annotations
we use for SkSharedMutex.
Change-Id: Ib91928bb9fcfa94f5cea985b46dea31ff2b56963
Reviewed-on: https://skia-review.googlesource.com/48580
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Herb Derby <herb@google.com>
Diffstat (limited to 'include/private')
-rw-r--r-- | include/private/SkMutex.h | 14 | ||||
-rw-r--r-- | include/private/SkTSAN.h | 76 |
2 files changed, 88 insertions, 2 deletions
diff --git a/include/private/SkMutex.h b/include/private/SkMutex.h index 7cfdb1132c..da9a80b00e 100644 --- a/include/private/SkMutex.h +++ b/include/private/SkMutex.h @@ -10,10 +10,15 @@ #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; @@ -21,10 +26,12 @@ 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(); } @@ -40,8 +47,11 @@ protected: class SkMutex : public SkBaseMutex { public: - using SkBaseMutex::SkBaseMutex; - ~SkMutex() { fSemaphore.cleanup(); } + SkMutex() { ANNOTATE_RWLOCK_CREATE(&fSemaphore); } + ~SkMutex() { + ANNOTATE_RWLOCK_DESTROY(&fSemaphore); + fSemaphore.cleanup(); + } }; class SkAutoMutexAcquire { diff --git a/include/private/SkTSAN.h b/include/private/SkTSAN.h new file mode 100644 index 0000000000..52f6bad4fe --- /dev/null +++ b/include/private/SkTSAN.h @@ -0,0 +1,76 @@ +/* + * 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 |