| Index: src/ports/SkBarriers_tsan.h
|
| diff --git a/src/ports/SkBarriers_tsan.h b/src/ports/SkBarriers_tsan.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ae68b3daf9d1865ca1414c17a0a4c2bc9c2d5727
|
| --- /dev/null
|
| +++ b/src/ports/SkBarriers_tsan.h
|
| @@ -0,0 +1,48 @@
|
| +/*
|
| + * 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 SkBarriers_tsan_DEFINED
|
| +#define SkBarriers_tsan_DEFINED
|
| +
|
| +#include <sanitizer/tsan_interface_atomic.h>
|
| +
|
| +static inline void sk_compiler_barrier() { asm volatile("" : : : "memory"); }
|
| +
|
| +// We'd do this as separate functions, but you can't partially specialize functions...
|
| +template <typename T, size_t bits>
|
| +struct SkBarriers {
|
| + static T AcquireLoad(T*);
|
| + static void ReleaseStore(T*, T);
|
| +};
|
| +
|
| +#define SK_BARRIERS(BITS) \
|
| + template <typename T> \
|
| + struct SkBarriers<T, BITS> { \
|
| + static T AcquireLoad(T* ptr) { \
|
| + return (T)__tsan_atomic ## BITS ## _load((__tsan_atomic ## BITS*)ptr, \
|
| + __tsan_memory_order_acquire); \
|
| + } \
|
| + static void ReleaseStore(T* ptr, T val) { \
|
| + __tsan_atomic ## BITS ## _store((__tsan_atomic ## BITS*)ptr, \
|
| + val, \
|
| + __tsan_memory_order_release); \
|
| + } \
|
| + }
|
| +SK_BARRIERS(8);
|
| +SK_BARRIERS(16);
|
| +SK_BARRIERS(32);
|
| +SK_BARRIERS(64);
|
| +#undef SK_BARRIERS
|
| +
|
| +template <typename T>
|
| +T sk_acquire_load(T* ptr) { return SkBarriers<T, 8*sizeof(T)>::AcquireLoad(ptr); }
|
| +
|
| +template <typename T>
|
| +void sk_release_store(T* ptr, T val) { SkBarriers<T, 8*sizeof(T)>::ReleaseStore(ptr, val); }
|
| +
|
| +
|
| +#endif//SkBarriers_tsan_DEFINED
|
|
|