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.


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.)


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".

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.


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