Commit d358cf09 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[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/+/1518176Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60202}
parent 9d45b49c
...@@ -10,15 +10,12 @@ ...@@ -10,15 +10,12 @@
#include <sched.h> #include <sched.h>
#endif #endif
#include "src/base/atomicops.h"
namespace v8 { namespace v8 {
namespace base { namespace base {
void CallOnceImpl(OnceType* once, std::function<void()> init_func) { void CallOnceImpl(OnceType* once, std::function<void()> init_func) {
AtomicWord state = Acquire_Load(once);
// Fast path. The provided function was already executed. // Fast path. The provided function was already executed.
if (state == ONCE_STATE_DONE) { if (once->load(std::memory_order_acquire) == ONCE_STATE_DONE) {
return; return;
} }
...@@ -29,23 +26,23 @@ void CallOnceImpl(OnceType* once, std::function<void()> init_func) { ...@@ -29,23 +26,23 @@ void CallOnceImpl(OnceType* once, std::function<void()> init_func) {
// //
// First, try to change the state from UNINITIALIZED to EXECUTING_FUNCTION // First, try to change the state from UNINITIALIZED to EXECUTING_FUNCTION
// atomically. // atomically.
state = Acquire_CompareAndSwap( uint8_t expected = ONCE_STATE_UNINITIALIZED;
once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_FUNCTION); if (once->compare_exchange_strong(expected, ONCE_STATE_EXECUTING_FUNCTION,
if (state == ONCE_STATE_UNINITIALIZED) { std::memory_order_acq_rel)) {
// We are the first thread to call this function, so we have to call the // We are the first thread to call this function, so we have to call the
// function. // function.
init_func(); init_func();
Release_Store(once, ONCE_STATE_DONE); once->store(ONCE_STATE_DONE, std::memory_order_release);
} else { } else {
// Another thread has already started executing the function. We need to // Another thread has already started executing the function. We need to
// wait until it completes the initialization. // 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 #ifdef _WIN32
::Sleep(0); ::Sleep(0);
#else #else
sched_yield(); sched_yield();
#endif #endif
state = Acquire_Load(once);
} }
} }
} }
......
...@@ -53,21 +53,22 @@ ...@@ -53,21 +53,22 @@
#define V8_BASE_ONCE_H_ #define V8_BASE_ONCE_H_
#include <stddef.h> #include <stddef.h>
#include <atomic>
#include <functional> #include <functional>
#include "src/base/atomicops.h"
#include "src/base/base-export.h" #include "src/base/base-export.h"
namespace v8 { namespace v8 {
namespace base { 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 #define V8_DECLARE_ONCE(NAME) ::v8::base::OnceType NAME
enum { enum : uint8_t {
ONCE_STATE_UNINITIALIZED = 0, ONCE_STATE_UNINITIALIZED = 0,
ONCE_STATE_EXECUTING_FUNCTION = 1, ONCE_STATE_EXECUTING_FUNCTION = 1,
ONCE_STATE_DONE = 2 ONCE_STATE_DONE = 2
...@@ -85,7 +86,7 @@ V8_BASE_EXPORT void CallOnceImpl(OnceType* once, ...@@ -85,7 +86,7 @@ V8_BASE_EXPORT void CallOnceImpl(OnceType* once,
std::function<void()> init_func); std::function<void()> init_func);
inline void CallOnce(OnceType* once, NoArgFunction 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); CallOnceImpl(once, init_func);
} }
} }
...@@ -94,7 +95,7 @@ inline void CallOnce(OnceType* once, NoArgFunction init_func) { ...@@ -94,7 +95,7 @@ inline void CallOnce(OnceType* once, NoArgFunction init_func) {
template <typename Arg> template <typename Arg>
inline void CallOnce(OnceType* once, inline void CallOnce(OnceType* once,
typename OneArgFunction<Arg*>::type init_func, Arg* arg) { 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); }); CallOnceImpl(once, [=]() { init_func(arg); });
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment