| Index: base/lazy_instance.cc
|
| diff --git a/base/lazy_instance.cc b/base/lazy_instance.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a1c80fb6b2cef71f79cde12c5a2dec8d51665212
|
| --- /dev/null
|
| +++ b/base/lazy_instance.cc
|
| @@ -0,0 +1,66 @@
|
| +// Copyright 2008 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/lazy_instance.h"
|
| +
|
| +#include "base/atomicops.h"
|
| +#include "base/basictypes.h"
|
| +
|
| +#if defined(OS_POSIX)
|
| +#include <sched.h>
|
| +#elif defined(OS_WIN)
|
| +#include <windows.h>
|
| +#endif
|
| +
|
| +namespace {
|
| +
|
| +void ThreadYield() {
|
| +#if defined(OS_POSIX)
|
| + sched_yield();
|
| +#elif defined(OS_WIN)
|
| + Sleep(0);
|
| +#endif
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace base {
|
| +namespace internal {
|
| +
|
| +// TODO(joth): This function could be shared with Singleton, in place of its
|
| +// WaitForInstance() call.
|
| +bool NeedsLazyInstance(subtle::AtomicWord* state) {
|
| + // Try to create the instance, if we're the first, will go from 0 to
|
| + // kLazyInstanceStateCreating, otherwise we've already been beaten here.
|
| + // The memory access has no memory ordering as state 0 and
|
| + // kLazyInstanceStateCreating have no associated data (memory barriers are
|
| + // all about ordering of memory accesses to *associated* data).
|
| + if (subtle::NoBarrier_CompareAndSwap(state, 0,
|
| + kLazyInstanceStateCreating) == 0)
|
| + // Caller must create instance
|
| + return true;
|
| +
|
| + // It's either in the process of being created, or already created. Spin.
|
| + // The load has acquire memory ordering as a thread which sees
|
| + // state_ == STATE_CREATED needs to acquire visibility over
|
| + // the associated data (buf_). Pairing Release_Store is in
|
| + // CompleteLazyInstance().
|
| + while (subtle::Acquire_Load(state) == kLazyInstanceStateCreating) {
|
| + ThreadYield();
|
| + }
|
| + // Someone else created the instance.
|
| + return false;
|
| +}
|
| +
|
| +void CompleteLazyInstance(subtle::AtomicWord* state,
|
| + subtle::AtomicWord new_instance,
|
| + void* lazy_instance) {
|
| + // Instance is created, go from CREATING to CREATED.
|
| + // Releases visibility over private_buf_ to readers. Pairing Acquire_Load's
|
| + // are in NeedsInstance() and Pointer().
|
| + subtle::Release_Store(state, new_instance);
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace base
|
|
|