Actions

icon Post
text/html Subscribe
text/html Unsubscribe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cxx-abi-dev] One-time Construction API (3.3.2)


  • To: Dennis Handly <dhandly@xxxxxxxxxx>
  • Subject: Re: [cxx-abi-dev] One-time Construction API (3.3.2)
  • From: Jason Merrill <jason@xxxxxxxxxx>
  • Date: Tue, 07 Sep 2004 17:17:45 -0400

On Thu, 05 Aug 2004 11:22:32 -0400, Jason Merrill <jason@xxxxxxxxxx> wrote:
> On Wed, 4 Aug 2004 22:45:21 -0700 (PDT), Dennis Handly <dhandly@xxxxxxxxxx> wrote:
>>>From: Jason Merrill <jason@xxxxxxxxxx>

>>>  To make this work, we need to do something like
>>>if (__cxa_guard_acquire (&guard)) {
>>
>> You didn't optimize by checking the guard before calling
>> _cxa_guard_acquire.
>
> Yep, I left that out for brevity.

It turns out that checking the guard is broken on the ia-64 platform unless
there is a memory barrier in the case that 'guard' is set.  This sort of
optimization is known as the Double Checked Locking Pattern, and is known
to be broken on modern architectures.

As described in this thread:

  http://www.google.com/groups?threadm=6kuldj$4sk%40bmtlh10.bnr.ca

the problem is that modern architectures can reorder stores and loads so
that another processor could see the guard variable set, but the controlled
variable not yet fully initialized.  The cheapest workaround is to add
memory barriers in the initialization path if the architecture reorders
stores (SPARC) and in the already-initialized path if it reorders loads
(Alpha, ia64).

Unfortunately, pthreads (for instance) don't have a portable way of forcing
a memory barrier other than with a mutex.

The simplest fix is just to remove the check in the compiler-generated
code, but...

>>>I've been thinking about how to implement the actual locking, and the best
>>>I've come up with is to have the guard be an index into an array of mutexes
>>
>> We use one mutex for all statics.  The same one that synchronizes the
>> __cxa_atexit list.
>
> Yes, that's a much simpler solution, and I think reasonable.

...this solution is much less reasonable if we need to acquire the mutex on
every call, not just the first one.

I think I will probably solve this problem by implementing a memory barrier
primitive in GCC.  What do you do?

Jason