Fw: [patch] Make std::tr1::shared_ptr thread-safe.

Alexander Terekhov alexander.terekhov@gmail.com
Fri Apr 1 00:05:00 GMT 2005


On Thu, 31 Mar 2005 22:32:42 +0200, Alexander Terekhov
<alexander.terekhov@gmail.com> wrote:
[...]
> > > void weak_release() throw() {
> > >   if (!self_count_.decrement(msync::acq, count::may_not_store_min))
> >
> > In an expanded form:
> >
> > - no memory synchronization when the result is not zero (old value > 1)
> > - acquire memory semantics when the old value is 1 (may skip the final store
> > of 0)
> 
> Yes. Assumption here is that on weak_ptr<> side we only increment and
> decrement self_count and don't make any other acceses to "control block"
> object apart from destruction and lock(). This allows to relax msync
> protocol.
> 
> Gosh. We need (relaxed) acquire in lock() for conditional increment
> (better than release constraint when the result is not zero for
> decrement in weak_release()).
> 
> Hmm. Now comes Whitehead (mutex inside lock())..
> 
> Without "real" fence in lock(), I don't see how to make it safe with
> relaxed msync protocol for self_count_.decrement() in weak_release().

Mutex dtor is another issue. So given that Peter says that it seems to 
him that in general lock() calls outnumber weak_release() calls, and 
that it's better to just use acq/rel in weak_release instead of 
modifying lock(), lets simply get rid of relaxation of acq/rel protocol 
on self_count() entirely. <pseudo-code>

class sp_counted_base {
 /* ... */
 typedef refcount<std::size_t, basic> count;
 count use_count_, self_count_;
 /* ... */
public:
 /* ... */
 sp_counted_base() : use_count_(1), self_count_(1) { }

 void add_ref() throw() {
   use_count_.increment(); // naked
 }

 void release() throw() {
   // "full" release-acquire protocol for decrements
   if (!use_count_.decrement()) { 
     dispose();
     if (!self_count_.decrement(count::may_not_store_min))
       destruct();
   }
 }

 bool lock() throw() {
   // Whitehead or
   return use_count_.increment_if_not_min(); // naked
 }

 void weak_add_ref() throw() {
   self_count_.increment(); // naked
 }

 void weak_release() throw() {
   // "full" release-acquire protocol
   if (!self_count_.decrement(count::may_not_store_min))
     destruct();
 }

 /* ... */

};

regards,
alexander.



More information about the Libstdc++ mailing list