V8 Project
once.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // emulates google3/base/once.h
6 //
7 // This header is intended to be included only by v8's internal code. Users
8 // should not use this directly.
9 //
10 // This is basically a portable version of pthread_once().
11 //
12 // This header declares:
13 // * A type called OnceType.
14 // * A macro V8_DECLARE_ONCE() which declares a (global) variable of type
15 // OnceType.
16 // * A function CallOnce(OnceType* once, void (*init_func)()).
17 // This function, when invoked multiple times given the same OnceType object,
18 // will invoke init_func on the first call only, and will make sure none of
19 // the calls return before that first call to init_func has finished.
20 //
21 // Additionally, the following features are supported:
22 // * A macro V8_ONCE_INIT which is expanded into the expression used to
23 // initialize a OnceType. This is only useful when clients embed a OnceType
24 // into a structure of their own and want to initialize it statically.
25 // * The user can provide a parameter which CallOnce() forwards to the
26 // user-provided function when it is called. Usage example:
27 // CallOnce(&my_once, &MyFunctionExpectingIntArgument, 10);
28 // * This implementation guarantees that OnceType is a POD (i.e. no static
29 // initializer generated).
30 //
31 // This implements a way to perform lazy initialization. It's more efficient
32 // than using mutexes as no lock is needed if initialization has already
33 // happened.
34 //
35 // Example usage:
36 // void Init();
37 // V8_DECLARE_ONCE(once_init);
38 //
39 // // Calls Init() exactly once.
40 // void InitOnce() {
41 // CallOnce(&once_init, &Init);
42 // }
43 //
44 // Note that if CallOnce() is called before main() has begun, it must
45 // only be called by the thread that will eventually call main() -- that is,
46 // the thread that performs dynamic initialization. In general this is a safe
47 // assumption since people don't usually construct threads before main() starts,
48 // but it is technically not guaranteed. Unfortunately, Win32 provides no way
49 // whatsoever to statically-initialize its synchronization primitives, so our
50 // only choice is to assume that dynamic initialization is single-threaded.
51 
52 #ifndef V8_BASE_ONCE_H_
53 #define V8_BASE_ONCE_H_
54 
55 #include "src/base/atomicops.h"
56 
57 namespace v8 {
58 namespace base {
59 
61 
62 #define V8_ONCE_INIT 0
63 
64 #define V8_DECLARE_ONCE(NAME) ::v8::base::OnceType NAME
65 
66 enum {
69  ONCE_STATE_DONE = 2
70 };
71 
72 typedef void (*NoArgFunction)();
73 typedef void (*PointerArgFunction)(void* arg);
74 
75 template <typename T>
77  typedef void (*type)(T);
78 };
79 
80 void CallOnceImpl(OnceType* once, PointerArgFunction init_func, void* arg);
81 
82 inline void CallOnce(OnceType* once, NoArgFunction init_func) {
83  if (Acquire_Load(once) != ONCE_STATE_DONE) {
84  CallOnceImpl(once, reinterpret_cast<PointerArgFunction>(init_func), NULL);
85  }
86 }
87 
88 
89 template <typename Arg>
90 inline void CallOnce(OnceType* once,
91  typename OneArgFunction<Arg*>::type init_func, Arg* arg) {
92  if (Acquire_Load(once) != ONCE_STATE_DONE) {
93  CallOnceImpl(once, reinterpret_cast<PointerArgFunction>(init_func),
94  static_cast<void*>(arg));
95  }
96 }
97 
98 } } // namespace v8::base
99 
100 #endif // V8_BASE_ONCE_H_
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
void(* NoArgFunction)()
Definition: once.h:72
void CallOnce(OnceType *once, NoArgFunction init_func)
Definition: once.h:82
void(* PointerArgFunction)(void *arg)
Definition: once.h:73
intptr_t AtomicWord
Definition: atomicops.h:57
Atomic32 Acquire_Load(volatile const Atomic32 *ptr)
AtomicWord OnceType
Definition: once.h:60
void CallOnceImpl(OnceType *once, PointerArgFunction init_func, void *arg)
Definition: once.cc:18
@ ONCE_STATE_UNINITIALIZED
Definition: once.h:67
@ ONCE_STATE_DONE
Definition: once.h:69
@ ONCE_STATE_EXECUTING_FUNCTION
Definition: once.h:68
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
void(* type)(T)
Definition: once.h:77
#define T(name, string, precedence)
Definition: token.cc:25