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>
This commit is contained in:
parent
7028443d1d
commit
e395bf2d18
@ -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 {
|
||||
|
76
include/private/SkTSAN.h
Normal file
76
include/private/SkTSAN.h
Normal file
@ -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
|
@ -8,68 +8,10 @@
|
||||
#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"
|
||||
|
Loading…
Reference in New Issue
Block a user