15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)subtle::AtomicWord WaitForInstance(subtle::AtomicWord* instance) { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle the race. Another thread beat us and either: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - Has the object in BeingCreated state 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - Already has the object created... 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unless your constructor can be very time consuming, it is very unlikely 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to hit this race. When it does, we just spin and yield the thread until 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the object has been created. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::AtomicWord value; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The load has acquire memory ordering as the thread which reads the 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // instance pointer must acquire visibility over the associated data. 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The pairing Release_Store operation is in Singleton::get(). 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) value = subtle::Acquire_Load(instance); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value != kBeingCreatedMarker) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThread::YieldCurrentThread(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35