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