This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On Thu, 31 Mar 2005 22:09:21 +0300, Peter Dimov <pdimov@mmltd.net> wrote:
> Alexander Terekhov wrote:
> > "Peter Dimov" <pdimov@mmltd.net> on 03/30/2005 11:33:56 PM:
> > [...]
> >> 3. Making __exchange_and_add offer the following memory
> >> synchronization guarantees:
> >>
> >> - acquire memory semantics when the result is not zero;
> >> - release memory semantics when the result is zero
> >
> > release memory semantics when the result is not zero;
> > acquire memory semantics when the result is zero
> 
> Umm, of course.
> 
> > And "result" means new value of count stored by __exchange_and_add(),
> > not return value (its old value). BTW, I had a typo in my previous
> > message when I wrote "result > 1".
> 
> [...]
> 
> > 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().

> 
> >     destruct();
> > }
> >
> > void release() throw() {
> >   if (!use_count_.decrement()) { // "full" release-acquire protocol
> 
> As above:
> 
> - release memory semantics when the result is not zero;
> - acquire memory semantics when the result is zero
> 
> >     dispose();
> >     if (!self_count_.decrement(msync::rel, count::may_not_store_min))
> 
> - release memory semantics when result is not zero (old value > 1)
> - no-op when the old value is 1 (no memory synchronization, may skip the
> final store of 0)
> 
> >       destruct();
> >   }
> > }
> 
> Right?

Right. But lock() must be MT-ordered with respect to destruction of 
control block and I missed that.

regards,
alexander.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]