5c9c9be1f5
The use of SKTRacy isn't safe in SkPathRef. There are logical dependencies between the racy fields. Doesn't seem to affect recording performance: $ c --match skp --config nonrendering tabl_techmeme.skp 81.1us -> 86us 1.06x desk_mapsvg.skp 1.23ms -> 1.26ms 1.02x desk_yahooanswers.skp 114us -> 117us 1.02x tabl_sahadan.skp 70.9us -> 72us 1.02x desk_fontwipe.skp 31.6us -> 32us 1.01x tabl_cuteoverload.skp 414us -> 419us 1.01x desk_mobilenews.skp 503us -> 508us 1.01x desk_tigersvg.skp 150us -> 152us 1.01x desk_samoasvg.skp 608us -> 610us 1x tabl_digg.skp 636us -> 638us 1x tabl_pravda.skp 155us -> 156us 1x desk_jsfiddlehumperclip.skp 33.9us -> 33.9us 1x tabl_culturalsolutions.skp 295us -> 295us 1x desk_youtube.skp 447us -> 448us 1x desk_gws.skp 144us -> 144us 1x tabl_frantzen.skp 42us -> 42us 1x tabl_gspro.skp 50.1us -> 50us 1x tabl_googlecalendar.skp 165us -> 165us 1x desk_twitter.skp 359us -> 358us 1x desk_wordpress.skp 588us -> 583us 0.99x desk_jsfiddlebigcar.skp 32.8us -> 32.5us 0.99x desk_booking.skp 838us -> 827us 0.99x tabl_androidpolice.skp 1.42ms -> 1.4ms 0.99x desk_blogger.skp 378us -> 372us 0.98x desk_wowwiki.skp 1.11ms -> 1.09ms 0.98x tabl_cnet.skp 115us -> 112us 0.97x desk_silkfinance.skp 57.7us -> 55.9us 0.97x tabl_cnn.skp 136us -> 131us 0.97x desk_sfgate.skp 396us -> 377us 0.95x tabl_deviantart.skp 107us -> 102us 0.95x tabl_mozilla.skp 1.4ms -> 1.32ms 0.94x BUG=437511 Review URL: https://codereview.chromium.org/762313002
86 lines
3.0 KiB
C++
86 lines
3.0 KiB
C++
/*
|
|
* Copyright 2014 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef SkDynamicAnnotations_DEFINED
|
|
#define SkDynamicAnnotations_DEFINED
|
|
|
|
// This file contains macros used to send out-of-band signals to dynamic instrumentation systems,
|
|
// namely thread sanitizer. This is a cut-down version of the full dynamic_annotations library with
|
|
// only the features used by Skia.
|
|
|
|
#if SK_DYNAMIC_ANNOTATIONS_ENABLED
|
|
|
|
extern "C" {
|
|
// TSAN provides these hooks.
|
|
void AnnotateIgnoreReadsBegin(const char* file, int line);
|
|
void AnnotateIgnoreReadsEnd(const char* file, int line);
|
|
void AnnotateIgnoreWritesBegin(const char* file, int line);
|
|
void AnnotateIgnoreWritesEnd(const char* file, int line);
|
|
void AnnotateBenignRaceSized(const char* file, int line,
|
|
const volatile void* addr, long size, const char* desc);
|
|
} // extern "C"
|
|
|
|
// SK_ANNOTATE_UNPROTECTED_READ can wrap any variable read to tell TSAN to ignore that it appears to
|
|
// be a racy read. This should be used only when we can make an external guarantee that though this
|
|
// particular read is racy, it is being used as part of a mechanism which is thread safe. Examples:
|
|
// - the first check in double-checked locking;
|
|
// - checking if a ref count is equal to 1.
|
|
// Note that in both these cases, we must still add terrifyingly subtle memory barriers to provide
|
|
// that overall thread safety guarantee. Using this macro to shut TSAN up without providing such an
|
|
// external guarantee is pretty much never correct.
|
|
template <typename T>
|
|
inline T SK_ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
|
|
AnnotateIgnoreReadsBegin(__FILE__, __LINE__);
|
|
T read = x;
|
|
AnnotateIgnoreReadsEnd(__FILE__, __LINE__);
|
|
return read;
|
|
}
|
|
|
|
// Like SK_ANNOTATE_UNPROTECTED_READ, but for writes.
|
|
template <typename T>
|
|
inline void SK_ANNOTATE_UNPROTECTED_WRITE(T* ptr, const T& val) {
|
|
AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
|
|
*ptr = val;
|
|
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
|
|
}
|
|
|
|
// Ignore racy reads and racy writes to this pointer, indefinitely.
|
|
// If at all possible, use the more precise SK_ANNOTATE_UNPROTECTED_READ.
|
|
template <typename T>
|
|
void SK_ANNOTATE_BENIGN_RACE(T* ptr) {
|
|
AnnotateBenignRaceSized(__FILE__, __LINE__, ptr, sizeof(*ptr), "SK_ANNOTATE_BENIGN_RACE");
|
|
}
|
|
|
|
#else // !SK_DYNAMIC_ANNOTATIONS_ENABLED
|
|
|
|
#define SK_ANNOTATE_UNPROTECTED_READ(x) (x)
|
|
#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val)
|
|
#define SK_ANNOTATE_BENIGN_RACE(ptr)
|
|
|
|
#endif
|
|
|
|
// Can be used to wrap values that are intentionally racy, usually small mutable cached values, e.g.
|
|
// - SkMatrix type mask
|
|
// - SkPixelRef genIDs
|
|
template <typename T>
|
|
class SkTRacy {
|
|
public:
|
|
operator const T() const {
|
|
return SK_ANNOTATE_UNPROTECTED_READ(fVal);
|
|
}
|
|
|
|
SkTRacy& operator=(const T& val) {
|
|
SK_ANNOTATE_UNPROTECTED_WRITE(&fVal, val);
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
T fVal;
|
|
};
|
|
|
|
#endif//SkDynamicAnnotations_DEFINED
|