
Ok, I see. I would try to explain. Let us look at pseudo code: *** BEGIN PSEUDO CODE *** static int* my_int = 0; static Mutex mutex; void CreateInt() { if(!my_int) { Locker locker(mutex); if(!my_int) my_int = new int(100); } } void thread_func() { boost::call_once(CreateInt, flag); printf("[%d]", *my_int); } void main() { th1 = create_thread(thread_func); th2 = create_thread(thread_func); while(1) { // Prints "[0][100]", or "[100][0]", or "[100][100]" - hm... undefined! } } *** END OF PSEUDO CODE *** Now I would try to explain the mysterious sense of my "I mean 'atomic' foo performance but not 'mutex'ed'" sentence. *** BEGIN EXPLANATION *** Let us imagine that boost::call_once has approximately this implementation (in pseudo code): call_once(function foo) { if(!called) { Locker locker; if(!called) { called = true; foo(); (1) } } } If you insert foo code at line (1), you will see the cascade of nested blocks like this: if(!flag1) { Locker locker; if(!flag2) // "Double Check Locking" { Locker locker; if(!flag3) // "Triple Check Locking" { Locker locker; ... ... ... foo(); ... ... ... } } } They say, that "Double Check Locking" is not thread-safe. They are right! See [http://www.ibm.com/developerworks/java/library/j-dcl.html] to look at "Double Check Locking" fault. So, "Triple Check Locking", "Quadro Check Locking" etc... are not thread-safe. "Atomic code" means the part of code, that is thread-safe. ATOMIC(code) ensures that "code" will be executed consistently with all threads. "Mutex'ed code" is the part of code, that is protected with mutex locker. I assume that boost::call_once does so: if(ATOMIC(!flag1)) // (2) { Locker locker; ... } I would like to ask Boost.Commutiny - is my assumption at line (2) the true? *** END OF EXPLANATION *** P.S. 1: Sorry for verbosity and complexity, if so. Best, Andrew. -- View this message in context: http://old.nabble.com/-Boost.utility--tp27309940p27347375.html Sent from the Boost - Dev mailing list archive at Nabble.com.