本文共 1504 字,大约阅读时间需要 5 分钟。
#include#include #include #include long CAS(volatile unsigned long **addr, long old, long *new){ /* https://www.felixcloutier.com/x86/cmpxchg: (* Accumulator = AL, AX, EAX, or RAX depending on whether a byte, word, doubleword, or quadword comparison is being performed *) TEMP ← DEST IF accumulator = TEMP (比较) THEN ZF ← 1; DEST ← SRC; ELSE ZF ← 0; accumulator ← TEMP; DEST ← TEMP; FI; Compares the value in the AL, AX, EAX, or RAX register with the first operand (destination operand). If the two values are equal, the second operand (source operand) is loaded into the destination operand. Otherwise, the destination operand is loaded into the AL, AX, EAX or RAX register. RAX register is available only in 64-bit mode. */ long ret = 0; __asm__ volatile (" lock; cmpxchg %4, %2" : "=a" (ret), "=m" (*addr) : "m" (*addr), "0" (old), "r" (new) : "cc" ); return ret == old;}static void *single = 0x0;void* getInstance(void * arg){ if (single != NULL) { return single; } long *p = calloc(1, sizeof(long)); *p = 8888; do{ if (single != NULL) break; if (CAS((volatile unsigned long **)&single, 0x0, p)) break; }while(1); return single;}
转载地址:http://lecii.baihongyu.com/