#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
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;
}
备份地址: 【使用CAS实现单例模式】