Subj : Re: posix and lock-free algorithms To : comp.programming.threads From : John Doug Reynolds Date : Thu Aug 11 2005 05:03 am > Singleton* Singleton::instance () { > Mutex m; > if (pInstance == 0) { > Lock lock; > if (pInstance == 0) { > Singleton* tmp = new Singleton; > m.lock(); m.unlock(); // just a memory barrier > pInstance = tmp; > > While this 'pInstance=tmp;' is executing, another thread could see > 'pInstance' as zero but not see the Singleton. Your error is in > thinking that the thread that creates the singleton invoking a > memory barrier has any effect on other threads that don't themselves > call memory barrier functions. > > Another thread could see 'pInstance == 0' and not see 'tmp' as > complete because that thread doesn't call any memory barrier > functions after testing pInstance but before accessing 'tmp'. > > } > } > else { m.lock(); m.unlock(); } // just a memory barrier > return pInstance; > } But the "reader" thread does place a memory barrier between its read of pInstance and any attempt to access *pInstance. If the "first check" fails (that is, pInstance != 0) in some thread, that thread immediately executes the second lock-unlock pair. If the "second check" fails in some thread, that thread will already have acquired the Lock and will immediately release it, thus creating a memory barrier. So all threads executing this code will encounter a memory barrier, one way or another. Doug .