Search This Blog

Friday, May 20, 2005

Atomic Functions - Part 3

Oh yeah, I forgot one function: AtomicSignedExchangeAdd. While this is admittedly a pretty odd function, it's quite important, as it'll be the first you get to see how real practical use of atomic functions works (at least on this blog).

// This could probably be made much faster with an inline assembly version
long AtomicSignedExchangeAdd(long volatile *lpnDest, long nAddend, bool bSigned)
{
assert(lpnDest);

long nValue;

// The basic principle of atomic access on RISC CPUs, and the principle of doing complex atomic operations at all: read, modify, try-write, repeat until we can pull it off without somebody screwing with it.
do
{
// Read the destination value and sign
nValue = *lpnDest;
bool bValueSign = (nValue < 0);

// Check if the sign matches the desired sign. If not, fail - we don't want to do the addition if the sign isn't correct.
if (bValueSign != bSigned)
break;

// Try to change the value from what it was to what we want (the specified value added). If the value has been changed since we read it, loop back and read it again.
} while (AtomicCompareExchange(lpnDest, nValue + nAddend, nValue) != nValue);

return nValue;
}

The comments weren't in the original code. I just added them in the hopes of making it more understandable than if I commented about how it works here :P

No comments: