Fw: [patch] Make std::tr1::shared_ptr thread-safe.
Paolo Carlini
pcarlini@suse.de
Sat Apr 2 19:43:00 GMT 2005
Peter Dimov wrote:
> Paolo Carlini wrote:
>
>> Thus, my question: missing a correct, fully-fenced, exchange_and_add,
>> is it possible a correct (albeit not optimally performing)
>> implementation?!? I think this very basic question has not received a
>> clear-cut answer yet. It is not a catastrophe if for 4.0.0 shared_ptr
>> works in MT only on a subset of the targets (only x86, x86_64, ia64,
>> for instance) but we *must* know, as soon as possible.
>
> It depends on what you mean by "correct". It will not be provably
> correct, but you'll probably not get a bug report against it... you
> haven't gotten a bug report against basic_string or locale::facet,
> either. (And, while I think I understand the theory, I am not positive
> that this can actually happen in practice.)
Thanks. This was also my understanding, but today Alexander's too much
"theoretician-biased" ;) remarks slighlty confused me. I'm an engineer,
you know, not a computer scientist... ;)
Therefore, I think we can safely say that Jonathan patch is OK, or at
least not worse, from the MT point of view than the rest of the library
(please correct me asap if I'm wrong!)
> In a nutshell, the problem is this:
>
> // thread 1
>
> access reference-counted object X
> drop reference to X
>
> // thread 2
>
> drop reference to X
> destroy X as a result
>
> If the two "drop reference" operations do not establish ordering, it
> is possible for the access to X from thread 1 to be executed after the
> destruction of X by thread 2.
>
> Let's take as an example the Alpha implementation that inserts memory
> barriers (the 'mb' instruction) after __exchange_and_add, but not before:
>
> // thread 1
>
> access reference-counted object X
> drop reference to X
> memory barrier
>
> // thread 2
>
> drop reference to X
> memory barrier
> destroy X as a result
>
> As you can see, thread 2's drop reference always precedes the
> destruction because of the memory barrier, but thread 1's drop can be
> reordered with the X access at will.
>
> For this not to happen, thread 1 needs a barrier between access and
> drop, which means that __exchange_and_add needs either a second "mb"
> barrier at the top, or inteligent execution of the mb instruction
> before or after the store depending on whether the result of the
> decrement means "no more references".
Got it. Many thanks for the nice summary.
> I repeat that this problem applies to every client of
> __exchange_and_add in libstdc++. It is not easy to make a test for it
> because the situation in which it happens is extremely rare and in
> most cases the reordered load will simply read from the
> just-deallocated memory without causing harm.
>
> I'll try to review basic_string and locale::facet so that I can speak
> in less general terms.
Yes, by now I think I understand the issue at large. Of course a review
of the usages in basic_string and locale::facet is very welcome. In any
case, I can confirm that after 4.0.0, when I will able devote 100% of my
time to this issue, we shall fix exchange_and_add itself.
Paolo.
More information about the Libstdc++
mailing list