10a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger/* 20a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Copyright 2013 Google Inc. 30a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * 40a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 50a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * found in the LICENSE file. 60a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */ 70a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 80a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifndef SkOnce_DEFINED 90a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#define SkOnce_DEFINED 100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// SkOnce.h defines SK_DECLARE_STATIC_ONCE and SkOnce(), which you can use 120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// together to create a threadsafe way to call a function just once. This 130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// is particularly useful for lazy singleton initialization. E.g. 140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// 150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// static void set_up_my_singleton(Singleton** singleton) { 16910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// *singleton = new Singleton(...); 170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// } 180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// ... 190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// const Singleton& GetSingleton() { 20910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// static Singleton* singleton = NULL; 21910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// SK_DECLARE_STATIC_ONCE(once); 22910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// SkOnce(&once, set_up_my_singleton, &singleton); 23910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// SkASSERT(NULL != singleton); 24910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// return *singleton; 250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// } 260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// 270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// OnceTest.cpp also should serve as a few other simple examples. 280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkThread.h" 300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTypes.h" 310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_USE_POSIX_THREADS 33910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger# define SK_ONCE_INIT { false, { PTHREAD_MUTEX_INITIALIZER } } 340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#else 35910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger# define SK_ONCE_INIT { false, SkBaseMutex() } 360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 38910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#define SK_DECLARE_STATIC_ONCE(name) static SkOnceFlag name = SK_ONCE_INIT 390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 40910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerstruct SkOnceFlag; // If manually created, initialize with SkOnceFlag once = SK_ONCE_INIT 41910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 42910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergertemplate <typename Func, typename Arg> 43910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerinline void SkOnce(SkOnceFlag* once, Func f, Arg arg); 440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// ---------------------- Implementation details below here. ----------------------------- 460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstruct SkOnceFlag { 480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool done; 490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBaseMutex mutex; 500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}; 510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// TODO(bungeman, mtklein): move all these *barrier* functions to SkThread when refactoring lands. 530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_BUILD_FOR_WIN 550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include <intrin.h> 560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline static void compiler_barrier() { 570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger _ReadWriteBarrier(); 580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#else 600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline static void compiler_barrier() { 610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger asm volatile("" : : : "memory"); 620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline static void full_barrier_on_arm() { 660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_CPU_ARM 670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#if SK_ARM_ARCH >= 7 680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger asm volatile("dmb" : : : "memory"); 690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#else 700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger asm volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); 710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// On every platform, we issue a compiler barrier to prevent it from reordering 760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// code. That's enough for platforms like x86 where release and acquire 770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// barriers are no-ops. On other platforms we may need to be more careful; 780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// ARM, in particular, needs real code for both acquire and release. We use a 790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// full barrier, which acts as both, because that the finest precision ARM 800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// provides. 810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline static void release_barrier() { 830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger compiler_barrier(); 840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger full_barrier_on_arm(); 850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline static void acquire_barrier() { 880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger compiler_barrier(); 890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger full_barrier_on_arm(); 900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// We've pulled a pretty standard double-checked locking implementation apart 930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// into its main fast path and a slow path that's called when we suspect the 940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// one-time code hasn't run yet. 950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// This is the guts of the code, called when we suspect the one-time code hasn't been run yet. 970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// This should be rarely called, so we separate it from SkOnce and don't mark it as inline. 980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// (We don't mind if this is an actual function call, but odds are it'll be inlined anyway.) 99910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergertemplate <typename Func, typename Arg> 100910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerstatic void sk_once_slow(SkOnceFlag* once, Func f, Arg arg) { 1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkAutoMutexAcquire lock(once->mutex); 1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!once->done) { 1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger f(arg); 1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // Also known as a store-store/load-store barrier, this makes sure that the writes 105910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger // done before here---in particular, those done by calling f(arg)---are observable 1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // before the writes after the line, *done = true. 1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // 1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // In version control terms this is like saying, "check in the work up 109910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger // to and including f(arg), then check in *done=true as a subsequent change". 1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // 111910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger // We'll use this in the fast path to make sure f(arg)'s effects are 1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // observable whenever we observe *done == true. 1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger release_barrier(); 1140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger once->done = true; 1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 1170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// We nabbed this code from the dynamic_annotations library, and in their honor 1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// we check the same define. If you find yourself wanting more than just 1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// ANNOTATE_BENIGN_RACE, it might make sense to pull that in as a dependency 1210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// rather than continue to reproduce it here. 1220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#if DYNAMIC_ANNOTATIONS_ENABLED 1240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// TSAN provides this hook to supress a known-safe apparent race. 1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerextern "C" { 1260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid AnnotateBenignRace(const char* file, int line, const volatile void* mem, const char* desc); 1270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 1280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#define ANNOTATE_BENIGN_RACE(mem, desc) AnnotateBenignRace(__FILE__, __LINE__, mem, desc) 1290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#else 1300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#define ANNOTATE_BENIGN_RACE(mem, desc) 1310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 1320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// This is our fast path, called all the time. We do really want it to be inlined. 134910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergertemplate <typename Func, typename Arg> 135910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerinline void SkOnce(SkOnceFlag* once, Func f, Arg arg) { 1360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger ANNOTATE_BENIGN_RACE(&(once->done), "Don't worry TSAN, we're sure this is safe."); 1370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!once->done) { 1380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger sk_once_slow(once, f, arg); 1390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // Also known as a load-load/load-store barrier, this acquire barrier makes 1410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // sure that anything we read from memory---in particular, memory written by 1420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // calling f(arg)---is at least as current as the value we read from once->done. 1430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // 1440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // In version control terms, this is a lot like saying "sync up to the 1450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // commit where we wrote once->done = true". 1460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // 1470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // The release barrier in sk_once_slow guaranteed that once->done = true 1480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // happens after f(arg), so by syncing to once->done = true here we're 1490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // forcing ourselves to also wait until the effects of f(arg) are readble. 1500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger acquire_barrier(); 1510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 1520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#undef ANNOTATE_BENIGN_RACE 1540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif // SkOnce_DEFINED 156