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