| Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | #include "src/base/once.h" | 
 | 6 |  | 
 | 7 | #ifdef _WIN32 | 
 | 8 | #include <windows.h> | 
 | 9 | #else | 
 | 10 | #include <sched.h> | 
 | 11 | #endif | 
 | 12 |  | 
 | 13 | #include "src/base/atomicops.h" | 
 | 14 |  | 
 | 15 | namespace v8 { | 
 | 16 | namespace base { | 
 | 17 |  | 
 | 18 | void CallOnceImpl(OnceType* once, PointerArgFunction init_func, void* arg) { | 
 | 19 |   AtomicWord state = Acquire_Load(once); | 
 | 20 |   // Fast path. The provided function was already executed. | 
 | 21 |   if (state == ONCE_STATE_DONE) { | 
 | 22 |     return; | 
 | 23 |   } | 
 | 24 |  | 
 | 25 |   // The function execution did not complete yet. The once object can be in one | 
 | 26 |   // of the two following states: | 
 | 27 |   //   - UNINITIALIZED: We are the first thread calling this function. | 
 | 28 |   //   - EXECUTING_FUNCTION: Another thread is already executing the function. | 
 | 29 |   // | 
 | 30 |   // First, try to change the state from UNINITIALIZED to EXECUTING_FUNCTION | 
 | 31 |   // atomically. | 
 | 32 |   state = Acquire_CompareAndSwap( | 
 | 33 |       once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_FUNCTION); | 
 | 34 |   if (state == ONCE_STATE_UNINITIALIZED) { | 
 | 35 |     // We are the first thread to call this function, so we have to call the | 
 | 36 |     // function. | 
 | 37 |     init_func(arg); | 
 | 38 |     Release_Store(once, ONCE_STATE_DONE); | 
 | 39 |   } else { | 
 | 40 |     // Another thread has already started executing the function. We need to | 
 | 41 |     // wait until it completes the initialization. | 
 | 42 |     while (state == ONCE_STATE_EXECUTING_FUNCTION) { | 
 | 43 | #ifdef _WIN32 | 
 | 44 |       ::Sleep(0); | 
 | 45 | #else | 
 | 46 |       sched_yield(); | 
 | 47 | #endif | 
 | 48 |       state = Acquire_Load(once); | 
 | 49 |     } | 
 | 50 |   } | 
 | 51 | } | 
 | 52 |  | 
| Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame^] | 53 | }  // namespace base | 
 | 54 | }  // namespace v8 |