Subj : Re: Can C++ local static objects be made thread safe? To : comp.programming.threads From : Gianni Mariani Date : Fri Jan 21 2005 05:41 am SenderX wrote: > > 1: static T volatile *shared = 0; > > 2: T *local = shared; > 3: ac_cpu_mb_consumer_depends(); /* Sync with 10 */ > 4: if ( ! local ) > 5: { ac_mutex_lock( &static_mutex ); > 6: local = shared; > 7: ac_cpu_mb_consumer_depends(); /* Sync with 10 */ > 8: if ( ! local ) > 9: { local = new T; > 10: ac_cpu_mb_producer(); /* Sync with 3 & 7 */ > 11: shared = local; /* Make visible to 4 & 8 after sync */ > 12: } > 13: ac_mutex_unlock( &static_mutex ); > 14: } > 15: return local; > > > This must be compiled so the code sequence is executed in the "exact" order > shown! All calls prefixed with 'ac_' are from my library. It seems as though ac_cpu_mb_consumer_depends() and ac_cpu_mb_producer(); are only applicable for non cache-coherent systems. Which architectures need memory barriers ? Obviosly uniprocessors are not an issue. CCNUMA machines are in theory, cahce cohereant, so do they require memory barriers ? Do all of these architectures have barrier instuctions with the same semantics ? Is this below going to perform as advertised ? ThreadLocal, MemoryBarrierSyncReads and MemoryBarrierSyncWrites are mythical things at this time. The idea is that once each thread has successfully traversed the initialization, it really doesn't need to bother synchronizing second time around. #define MTSafeStatic( Type, Name, Initializer ) \ static Type * x_ ## Name; \ Type * xlocal_ ## Name = x_ ## Name; \ \ ThreadLocal m_val; \ \ if ( ! m_val ) \ { \ MemoryBarrierSyncReads(); \ } \ \ if ( ! xlocal_ ## Name ) \ { \ Lock l_lock( StaticInitializerMutex ); \ \ if ( ! x_ ## Name ) \ { \ static Type v_ ## Name Initializer; \ \ MemoryBarrierSyncWrites(); \ x_ ## Name = & v_ ## Name ; \ xlocal_ ## Name = & v_ ## Name; \ } \ } \ \ m_val = true; \ \ Type & Name = * xlocal_ ## Name; \ // End macro .