Subj : Re: A question about atomic_ptr To : comp.programming.threads From : Chris Thomasson Date : Sun Apr 17 2005 01:48 am >> But there's one other thing: shared_ptr is two pointers, not one. Without >> DWCAS, or at least double-wide atomic loads and stores, even hazards >> aren't >> enough to make it atomic. :-( > > Humm... There should be a way. I will try to apply my SMR implementation > to your shared_ptr< T > and see what I can come up with. I think I may be getting somewhere. I made the following additions to shared_ptr API: // *** detail::sp_counted_base *** 1. *Add this to private section: ----------------- static void AC_CDECL lfgc_dtor( void *s ) { ac_cpu_node_t *node = (ac_cpu_node_t*)s; delete (sp_counted_base*)node->state; ac_thread_cpu_node_cache_push( ac_thread_self(), node ); } struct ac_lfgc_node_t { ac_cpu_node_t *m_node; void init( sp_counted_base *_base ) { m_node = ac_thread_cpu_node_cache_pop ( ac_thread_self(), _base ); } void collect() { if ( m_node ) { ac_cpu_node_t *node = m_node; m_node = 0; ac_i686_lfgc_smr_collect ( ac_thread_self(), lfgc_dtor, node ); } } }; ac_lfgc_node_t m_node; 2. *Add this to public section: ----------------- bool add_ref_lock_if_greater_than_zero() { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif if(use_count_ == 0) { return false; } ++use_count_; return true; } 3. *Change the ctor to: ----------------- sp_counted_base(): use_count_(1), weak_count_(1) { m_node.init( this ); } 4. *Change the destruct to: ----------------- virtual void destruct() { m_node.collect(); } // *** detail::shared_count *** 1. *Add this to public section: ----------------- void tricky_copy( shared_count &r ) // nothrow { sp_counted_base *src, *old = pi_; ac_thread_t *_tls = ac_thread_self(); ac_i686_lfgc_smr_hazard_t hazard = ac_lfgc_smr_get( _tls, 0 ); do { src = (sp_counted_base*) ac_lfgc_smr_activate ( hazard, (ac_cpu_node_t**)&r.pi_ ); if ( ! src ) { break; } } while ( ! src->add_ref_lock_if_greater_than_zero() ); pi_ = src; if ( old ) { old->release(); } if ( src ) { ac_lfgc_smr_deactivate( hazard ); } } // *** shared_ptr *** 1. *Add this to public section: ----------------- void tricky_copy( shared_ptr &r ) { pn.tricky_copy( r.pn ); px = r.px; } I believe shared_ptr can work well with SMR using these ad-hoc tweaks... I am going to run some tests and study the shared_ptr impl a bit more to be totally sure... :) .