diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 13:31:49 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 13:31:49 +0000 |
commit | 6de0fd1d935e8c6c9257f1082dbd227acb1a06b1 (patch) | |
tree | 0ed5bc4ef9c2da0b498c30e562218f4528eaac9e /base/lazy_instance.cc | |
parent | 0f86c358fdb5e47aa9cd4a99b12da5e66507d080 (diff) | |
download | chromium_src-6de0fd1d935e8c6c9257f1082dbd227acb1a06b1.zip chromium_src-6de0fd1d935e8c6c9257f1082dbd227acb1a06b1.tar.gz chromium_src-6de0fd1d935e8c6c9257f1082dbd227acb1a06b1.tar.bz2 |
Allow linker initialization of lazy instance
Using the initializer list construct = {0} allows the object to be linker initialized.
Modify the LazyInstance class design to make it a pod aggregate type that can be linker initialized this way. Also combines the instance and state members, in line with the Singleton<> class design.
Introduces a new LAZY_INSTANCE_INITIALIZER macro specifically for using to init all lazy instances + modify all existing callsites to use it. (Old code would no longer compile)
BUG=94925
TEST=existing tests pass. http://build.chromium.org/f/chromium/perf/linux-release/sizes/report.html?history=150&header=chrome-si&graph=chrome-si&rev=-1 should step downward.
TBR=jam@chromium.org,rvargas@chromium.org,darin@chromium.org,ben@chromium.org,apatrick@chromium.org,akalin@chromium.org
Review URL: http://codereview.chromium.org/8491043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110076 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/lazy_instance.cc')
-rw-r--r-- | base/lazy_instance.cc | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/base/lazy_instance.cc b/base/lazy_instance.cc index 1be3488..a81cb8c 100644 --- a/base/lazy_instance.cc +++ b/base/lazy_instance.cc @@ -11,15 +11,18 @@ #include "base/third_party/dynamic_annotations/dynamic_annotations.h" namespace base { - -bool LazyInstanceHelper::NeedsInstance() { - // Try to create the instance, if we're the first, will go from EMPTY - // to CREATING, otherwise we've already been beaten here. - // The memory access has no memory ordering as STATE_EMPTY and STATE_CREATING - // has no associated data (memory barriers are all about ordering - // of memory accesses to *associated* data). - if (base::subtle::NoBarrier_CompareAndSwap( - &state_, STATE_EMPTY, STATE_CREATING) == STATE_EMPTY) +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; @@ -27,29 +30,30 @@ bool LazyInstanceHelper::NeedsInstance() { // 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 - // CompleteInstance(). - while (base::subtle::Acquire_Load(&state_) != STATE_CREATED) + // CompleteLazyInstance(). + while (subtle::Acquire_Load(state) == kLazyInstanceStateCreating) { PlatformThread::YieldCurrentThread(); - + } // Someone else created the instance. return false; } -void LazyInstanceHelper::CompleteInstance(void* instance, void (*dtor)(void*)) { +void CompleteLazyInstance(subtle::AtomicWord* state, + subtle::AtomicWord new_instance, + void* lazy_instance, + void (*dtor)(void*)) { // See the comment to the corresponding HAPPENS_AFTER in Pointer(). - ANNOTATE_HAPPENS_BEFORE(&state_); + ANNOTATE_HAPPENS_BEFORE(state); // Instance is created, go from CREATING to CREATED. - // Releases visibility over buf_ to readers. Pairing Acquire_Load's are in - // NeedsInstance() and Pointer(). - base::subtle::Release_Store(&state_, STATE_CREATED); + // Releases visibility over private_buf_ to readers. Pairing Acquire_Load's + // are in NeedsInstance() and Pointer(). + subtle::Release_Store(state, new_instance); // Make sure that the lazily instantiated object will get destroyed at exit. if (dtor) - base::AtExitManager::RegisterCallback(dtor, instance); + AtExitManager::RegisterCallback(dtor, lazy_instance); } +} // namespace internal } // namespace base - - - |