#endif
#ifndef SK_BARRIERS_PLATFORM_H
-# if defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
+# if SK_HAS_COMPILER_FEATURE(thread_sanitizer)
+# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_tsan.h"
+# elif defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h"
# else
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h"
--- /dev/null
+/*
+ * 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
# Not threadsafe, should be fixed.
race:RefFCI
-race:SkString::RefRec
+race:SkString
# Not threadsafe, should be deleted.
race:SkPDF
-
-# Should be these can be removed once TSAN learns sk_acquire_load / sk_release_store.
-race:SkOnce
-race:SkRefCntBase
-
-# This is SkLazyPtr. Also can be cleaned up when TSAN learns sk_acquire_load / sk_release_store.
-race:sk_acquire_load
-race:__tsan_atomic64_compare_exchange_val