here is CAS, CAS2 macros
#ifdef __x86_64__
#define __xg(x) ((volatile long *)(x)) // stole from linux kernel source
// CAS2(ret, &q->tail, head, tag2, next, tag2 + 1);
#define CAS2(ret, mem, old1, old2, new1, new2) \
do {\
asm volatile( \
".align 8 \n" \
"movq $0, %0 \n" \
"LOCK cmpxchg16b %1\n" \
"setz %0 \n" \
"1:\n" \
: "=m" (ret) \
: "m" (*__xg(mem)), "a" (old1), "d" (old2), "b" (new1), "c" (new2) \
: "memory", "cc" \
); \
/* ret = ( (ret & (1 <<>
} while(0);#else#define CAS2(ret, mem, old1, old2, new1, new2) \do {\asm volatile( \".align 4 \n" \"movl $0, %0 \n" \"LOCK cmpxchg8b (%%esi)\n" \"setz %0 \n" \"1:\n" \: "=m" (ret) \: "S" (mem), "a" (old1), "d" (old2), "b" (new1), "c" (new2) \: "memory", "cc" \); \/* ret = ( (ret & (1 <<>} while(0);#endif#define DEAD_NODE(q) \&((q)->stone)#ifdef __x86_64__#define CAS(ret, mem, old, new) \do {\asm volatile( \".align 8 \n" \"movq $0, %0 \n" \"LOCK cmpxchgq %1, %2 \n" \"setz %0 \n" \: "=m" (ret) \: "d" (new), "m" (*__xg(mem)), "a" (old) \: "memory", "cc" \); \} while(0);#else#define CAS(ret, mem, old, new) \do {\asm volatile( \".align 4 \n" \"movl $0, %0 \n" \"LOCK cmpxchgl %%edx, (%%esi) \n" \"setz %0 \n" \: "=m" (ret) \: "d" (new), "S" (mem), "a" (old) \: "memory", "cc" \); \} while(0);#endif
Note: you will have to use long/unsigned long type for each variables for CAS/CAS2, if use int type, gcc might use e*x registers as operand of q suffix instructions, it will make you very unhappy.