apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Justin Erenkrantz" <jus...@erenkrantz.com>
Subject Re: Patch 1 for apr_atomic.c (Solaris 10)
Date Mon, 30 Oct 2006 07:58:08 GMT
On 10/30/06, Colin <share-apache@think42.com> wrote:
> Erm, memory barriers aren't things that need to be "acquired" and
> "released"; think of them as synchronisation points. Reasoning about
> just one CPU we could say that a memory barrier ensures that all
> memory operations that, in the instruction stream, occur before the
> barrier, are also actually performed before the barrier, and that no
> memory operation that, in the instruction stream, occurs after the
> barrier, is performed before the barrier (at least that's the case
> for the most general two-way read-write-barrier).
> An atomic write operation (to an appropriately sized object) therefore
> simply means that a CPU, on the bus, actually performs the write in a
> way that other CPUs can/must see it.
> Similarly an atomic read does not acquire anything, it just must make
> sure that the read operation actually takes place, and takes into
> account any changes to the data that another CPU might have made.
> Does this halfway explain why they are necessary?
> On further thought: Perhaps you are mixing up memory barriers and the
> "load-locked, store-conditional" pair of memory accesses?

According to the Solaris 10 manual, I'm not sure that your description
matches.  AFAICT from just the manual, the membar_enter() function
blocks the system from doing any store/loads until membar_exit() is

     The membar_enter() function is a generic memory barrier used
     during  lock  entry. It is placed after the memory operation
     that acquires the lock to guarantee that the  lock  protects
     its data. No stores from after the memory barrier will reach
     visibility and no loads  from  after  the  barrier  will  be
     resolved before the lock acquisition reaches global visibil-

     The membar_exit() function is a generic memory barrier  used
     during lock exit. It is placed before the      memory opera-
     tion that releases the lock to guarantee that the lock  pro-
     tects  its data. All loads and stores issued before the bar-
     rier      will be resolved before the subsequent lock update
     reaches visibility.

     The membar_enter()  and  membar_exit()  functions  are  used
     together  to  allow  regions  of code to be in relaxed store
     order and then ensure that the load or store order is  main-
     tained at a higher level. They are useful in the implementa-
     tion of mutex exclusion locks.

Now, if I look at the actual implementation of
membar_enter()/membar_exit() for Solaris, it becomes a bit clearer:


The both use 'mfence' on AMD64. The AMD x86-64 manual:


'mfence' is on page 182 of Vol 3:

Acts as a barrier to force strong memory ordering (serialization)
between load and store instructions preceding the MFENCE, and load and
store instructions that follow the MFENCE. A weakly-ordered memory
system allows the hardware to reorder reads and writes between the
processor and memory. The MFENCE instruction guarantees that the
system completes all previous memory accesses before executing
subsequent accesses.

So, in response to my question about whether membar_enter() needs a
call to membar_exit(), the answer is apparently 'no.'  membar_enter()
and membar_exit() have no real relationship to each other - it just
indicates when they should be invoked not that it actually does
anything.  It seems that the folks at Sun just picked horrible names
for this API.

Thanks for clarifying.

So, if I run 'testatomic' it should just do everything I need in order
to test this, right?  Or, should we shore up those tests too?  If
'testatomic' is sufficient, I can test on Sparc and x86 later this
week if no one beats me to it.

Thanks.  -- justin

View raw message