Search This Blog

Friday, May 20, 2005

Atomic Functions - Part 4

And finally, for icing on the cake, the Mac version (not that it's ever been compiled and tested on a Mac...), with self-documenting comments:

  asm
long // <- Initial value of *addr (r3).
AtomicCompareExchange(
long volatile *addr, // -> Location to update (r3).
long next, // -> New value (r4).
long prev) // -> Previous value (r5).
{
retry:
lwarx r6, 0, r3 // current = *addr;
cmpw r6, r5 // if( current != prev )
bne fail // goto fail;
stwcx. r4, 0, r3 // if( reservation == *addr ) *addr = next;
bne- retry // else goto retry;
mr r3, r6 // Return current.
blr // We're outta here.
fail:
stwcx. r6, 0, r3 // Clear reservation.
mr r3, r6 // Return current.
blr // We're outta here.
}

Note that this was taken from IBM's site; I modified it a little bit to match my own applications.

You might notice that the rest of the atomic functions aren't here. I left them out in the hopes of avoiding further pages of boring code, when they're all essentially the same as the AtomicSignedExchangeAdd in the last post (they all use AtomicCompareExchange exclusively).

All this inline assembly is pretty boring. Things should get more interesting once I get into the classes, how they work, and how they may be emulated on some platforms.

No comments: