gallatin at cs.duke.edu
Thu Aug 7 07:33:07 PDT 2003
Daniel Eischen writes:
> [ I'm not subscribed to alpha@; please keep me on the CC ]
> I need an atomic swap function for libpthread. Here's my hack
> of an implementation:
> * Atomic swap:
> * Atomic (tmp = *dst, *dst = val), then *res = tmp
> * void atomic_swap_long(long *dst, long val, long *res);
> static __inline
> void atomic_swap_long(volatile long *dst, long val, long *res)
> u_int64_t result;
> __asm __volatile (
> "1:\tldq_l %0,%1\n\t"
> "stq_c %2,%1\n\t"
> "beq %2,2f\n\t" /* Why is this beq instead of bne 1b? */
> "br 3f\n"
> "2:\tbr 1b\n"
> : "=&r" (result)
> : "m" (*dst), "r" (val)
> : "memory");
> *res = result;
> As annotated above, there seems to be one more branch than
Its actually an optimization. Alphas predict that backward branches
will always be taken (think loops). If you were to branch directly
back to 1:, then if the store succeeds (which it nearly always
should), then the cpu would have been betting on taking the branch,
and that would slow things down.
> Can someone look this over for me? I really don't quite
> know what I'm doing when it comes to inline assembly.
I think it looks OK, but I'm also terrible at inline asm.
More information about the freebsd-alpha