#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实现单例模式