Hi dee Ho peeps!
I was pondering how to implement atomic compare and swap (for ix86 at starters) in such a way that return value would tell what the value was pefore instruction was executed. I could write:
Code:
int __inline__ atomicCAS( volatile unsigned int *ptr, int cmp, int new)
{
unsigned char ret;
unsigned int original = *ptr;
__asm__ __volatile__ (
" lock\n"
" cmpxchgl %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (new), "m" (*ptr), "a" (cmp)
: "memory");
return original;
}
But now, in case the *ptr == cmp when value of original is set, there's possibility that something changes the value before we call the asm code.
=> return value would indicate that swap occurred, but in reality it did not.
My asm skills are *limited*, and I cannot bend my mind around this problem. I of course could just do:
Code:
int __inline__ atomicCAS( volatile unsigned int *ptr, int cmp, int new)
{
unsigned char ret;
__asm__ __volatile__ (
" lock\n"
" cmpxchgl %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (new), "m" (*ptr), "a" (cmp)
: "memory");
return (int) ret;
}
where return value just says whether the swap took place, but it would be handy at times to be able to tell what the swapped out value was.
Any ideas?
(I have been googling, and read that this kind of function returning original memory contents is usual way to do CAS, so I assume there is a way).