[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:
Clemens Hammacher 2019-03-12 15:57:10 +01:00 committed by Commit Bot
parent 9d45b49cc2
commit d358cf098c
2 changed files with 14 additions and 16 deletions

View File

@ -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);
}
}
}

View File

@ -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); });
}
}