More on memory barriers

Jason Merrill jason@redhat.com
Wed Sep 15 21:36:00 GMT 2004


On Wed, 15 Sep 2004 13:10:32 -0700, Richard Henderson <rth@redhat.com> wrote:

> On Wed, Sep 15, 2004 at 11:43:32AM -0400, Jason Merrill wrote:
>> > Well, no, Alpha needs
>> >
>> >   read_memory_barrier ();
>> >   if (!initialized)
>> >[...]
>> 
>> Hmm?  Why do we need the read barrier on the initialization path?  I would
>> expect the mutex to provide enough of a read barrier.
>
> This is *exactly* what the messages you pasted at me the other day 
> were explaining.  Go back and re-read them.

No, the messages were explaining why we need the read barrier on the
*non*-initialization path, where we're avoiding the mutex.

I understand why the memory barrier is needed, my question had to do with
why it would need to look like

MB
if (test)
  initialize

rather than

if (test)
  initialize
else
  MB

since "initialize" already contains a MB in the form of a mutex lock.

>> By "release barrier" I meant annotating the assignment to initialized with
>> .rel, which I would expect to be less expensive than __sync_synchronize.
>> But you would know better than I.
>
> No.  You need ordering between the constructor and the setting
> of initialize.  Release semantics on stores happen *after* the
> store.  There is no st.acq for getting a barrier before a store,
> so in order to get a barrier before, we must use "mf".

Ah, OK.

> As far as I know, "mf" is no more expensive that that -- just another
> instruction on the stream.  All barriers, .rel, .acq, mf, are equivalent
> strength, just the encoding and logical placement differs.

The Itanium ABI manual that documents the __sync intrinsics distinguishes
between acquire barriers (disallow movement from after the barrier to
before it), release barriers (disallow movement from before the barrier to
after it), and full barriers (disallow all movement of memory references
across the barrier).

Jason



More information about the Gcc mailing list