幾乎全部的CPU指令都支持CAS的原子操做,X86下對應的是 CMPXCHG 彙編指令。有了這個原子操做,咱們就能夠用其來實現各類無鎖(lock free)的數據結構。數據結構
int compare_and_swap_return_i(int *reg,int old_value,int new_value) { int reg_vlaue=*reg; if (reg_vlaue==old_value) { *reg=new_value; } return *reg; } bool compare_and_swap_return_b(int *reg,int old_value,int new_value) { int reg_vlaue=*reg; if (reg_vlaue==old_value) { *reg=new_value; return true; } return false; }
用cas實現鎖:fetch
#define lock(lkp) do{ \ while(!compare_and_swap_return_b(lkp, 0, 1)){ \ sched_yield(); \ } \ }while(0);
其中:sched_yield()是讓出CPU。atom
#define unlock(lkp) do{ \ *(lkp) = 0; \ }while(0);
#define try_lock(lkp) ({ \ (compare_and_swap_return_b(lkp, 0, 1) ? 0 : -1); \ });
除了CAS,還有 Fetch_And_Add:code
int fetch_and_add(int* variable, int value)//通常用來對變量作 +1 的原子操 { __asm__ volatile("lock; xaddl %0, %1" : "+r" (value), "+m" (*variable) // input+output : // No input-only : "memory" ); return value; }
TestAndSet:ip
int TestAndSet(int* lockPtr) { int oldValue; oldValue = *lockPtr; *lockPtr = LOCKED; return oldValue; }
Test and test-and-set:input
boolean locked := false // shared lock variable procedure EnterCritical() { do { while (locked == true) skip // spin until lock seems free } while TestAndSet(locked) // actual atomic locking }
Exit protocol is:it
procedure ExitCritical() { locked := false }