[base] Switch Once to std::atomic
We want to get rid of the atomicops library, hence switch all uses to std::atomic. R=mlippautz@chromium.org Bug: v8:8926, v8:8834 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel Change-Id: I7966d4ea98c5dd2ff712b1d84a6877f407f55ec7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1518176 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#60202}
This commit is contained in:
parent
9d45b49cc2
commit
d358cf098c
@ -10,15 +10,12 @@
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#include "src/base/atomicops.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
|
||||
void CallOnceImpl(OnceType* once, std::function<void()> init_func) {
|
||||
AtomicWord state = Acquire_Load(once);
|
||||
// Fast path. The provided function was already executed.
|
||||
if (state == ONCE_STATE_DONE) {
|
||||
if (once->load(std::memory_order_acquire) == ONCE_STATE_DONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -29,23 +26,23 @@ void CallOnceImpl(OnceType* once, std::function<void()> init_func) {
|
||||
//
|
||||
// First, try to change the state from UNINITIALIZED to EXECUTING_FUNCTION
|
||||
// atomically.
|
||||
state = Acquire_CompareAndSwap(
|
||||
once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_FUNCTION);
|
||||
if (state == ONCE_STATE_UNINITIALIZED) {
|
||||
uint8_t expected = ONCE_STATE_UNINITIALIZED;
|
||||
if (once->compare_exchange_strong(expected, ONCE_STATE_EXECUTING_FUNCTION,
|
||||
std::memory_order_acq_rel)) {
|
||||
// We are the first thread to call this function, so we have to call the
|
||||
// function.
|
||||
init_func();
|
||||
Release_Store(once, ONCE_STATE_DONE);
|
||||
once->store(ONCE_STATE_DONE, std::memory_order_release);
|
||||
} else {
|
||||
// Another thread has already started executing the function. We need to
|
||||
// wait until it completes the initialization.
|
||||
while (state == ONCE_STATE_EXECUTING_FUNCTION) {
|
||||
while (once->load(std::memory_order_acquire) ==
|
||||
ONCE_STATE_EXECUTING_FUNCTION) {
|
||||
#ifdef _WIN32
|
||||
::Sleep(0);
|
||||
#else
|
||||
sched_yield();
|
||||
#endif
|
||||
state = Acquire_Load(once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,21 +53,22 @@
|
||||
#define V8_BASE_ONCE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
|
||||
#include "src/base/atomicops.h"
|
||||
#include "src/base/base-export.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
|
||||
typedef AtomicWord OnceType;
|
||||
using OnceType = std::atomic<uint8_t>;
|
||||
|
||||
#define V8_ONCE_INIT 0
|
||||
#define V8_ONCE_INIT \
|
||||
{ 0 }
|
||||
|
||||
#define V8_DECLARE_ONCE(NAME) ::v8::base::OnceType NAME
|
||||
|
||||
enum {
|
||||
enum : uint8_t {
|
||||
ONCE_STATE_UNINITIALIZED = 0,
|
||||
ONCE_STATE_EXECUTING_FUNCTION = 1,
|
||||
ONCE_STATE_DONE = 2
|
||||
@ -85,7 +86,7 @@ V8_BASE_EXPORT void CallOnceImpl(OnceType* once,
|
||||
std::function<void()> init_func);
|
||||
|
||||
inline void CallOnce(OnceType* once, NoArgFunction init_func) {
|
||||
if (Acquire_Load(once) != ONCE_STATE_DONE) {
|
||||
if (once->load(std::memory_order_acquire) != ONCE_STATE_DONE) {
|
||||
CallOnceImpl(once, init_func);
|
||||
}
|
||||
}
|
||||
@ -94,7 +95,7 @@ inline void CallOnce(OnceType* once, NoArgFunction init_func) {
|
||||
template <typename Arg>
|
||||
inline void CallOnce(OnceType* once,
|
||||
typename OneArgFunction<Arg*>::type init_func, Arg* arg) {
|
||||
if (Acquire_Load(once) != ONCE_STATE_DONE) {
|
||||
if (once->load(std::memory_order_acquire) != ONCE_STATE_DONE) {
|
||||
CallOnceImpl(once, [=]() { init_func(arg); });
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user