Atomic swap

Daniel Eischen eischen at vigrid.com
Thu Aug 7 12:31:57 PDT 2003


On Thu, 7 Aug 2003, Marcel Moolenaar wrote:

> On Thu, Aug 07, 2003 at 03:06:33PM -0400, Portante, Peter wrote:
> > Marcel,
> > 
> > > atomic_swap_long(volatile long *dst, long val, long *res)
> > > {
> > > 	__asm (	"1: ldq_l   t0,%0\n"
> > > 		"   mov     %1,t1\n"
> > > 		"   stq_c   t1,%0\n"
> > > 		"   beq     t1,1b\n"
> > > 		"   stq     t0,%3\n"
> 		^^^^^^^^^^^^^^^^^^^^
> 
> Whoops, typo: %3 should be %2.

Yup, I caught that but didn't want to complain when something
is handed to me on a silver platter ;-)

> > > 	    :: "m"(*dst), "r"(val), "m"(*res) : "memory");
> > > }
> > > 
> > A word of caution on performing that stq without an MB before it:
> > another processor cannot read that location and the destination
> > location and assume anything about their contents based on what
> > they read unless an MB is between them.
> 
> Good point. I don't think we have to worry about it, though. This
> function has a specific usage (see src/lib/libpthread/sys/lock.c).
> If I understand the code correctly, *res is never used other than
> the caller of atomic_swap_long that writes to *res.

Yes, perhaps the interface should be:

    long atomic_swap_long(volatile long *dst, long val)

instead of having the result as the 3rd argument.  But it's
already used this way in libpthread, so I didn't want to
change it.  I can always do that later.

Hmm, it would be nice just to have atomic_swap (or atomic_xchg,
or whatever you want to call it) in <machine/atomic.h>.

-- 
Dan Eischen



More information about the freebsd-alpha mailing list