This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Fw: [patch] Make std::tr1::shared_ptr thread-safe.
- From: Alexander Terekhov <alexander dot terekhov at gmail dot com>
- To: Peter Dimov <pdimov at mmltd dot net>
- Cc: libstdc++ at gcc dot gnu dot org, Jonathan Wakely <cow at compsoc dot man dot ac dot uk>
- Date: Thu, 31 Mar 2005 22:32:42 +0200
- Subject: Re: Fw: [patch] Make std::tr1::shared_ptr thread-safe.
- References: <OF24DE43AB.98214558-ONC1256FD5.0044D61E-C1256FD5.0044BD18@de.ibm.com> <e52efbe105033105212ee0988a@mail.gmail.com> <013201c53625$27348390$6501a8c0@pdimov2>
- Reply-to: Alexander Terekhov <alexander dot terekhov at gmail dot com>
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.