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.