nginx自旋锁
#include <stdio.h> #include <stdint.h> #include <unistd.h> /* typedef unsigned long ngx_atomic_uint_t; typedef volatile ngx_atomic_uint_t ngx_atomic_t; typedef long ngx_atomic_int_t; #define ngx_atomic_cmp_set(lock, old, set) __sync_bool_compare_and_swap(lock, old, set) */ #define my_unlock(lock) *(lock) = 0 //lock: 原子变量表达的锁 //value:标志位,锁是否被某一进程占用,一般情况下为进程pid //spin: 在多处理器系统内,当my_spinlock方法没有拿到锁时,当前进程在内核的一次调度中该方法等待其他处理器释放锁的时间 void my_spinlock(volatile unsigned long *lock,long value,uintptr_t spin) { uintptr_t i,n; while(1){ //lock为0表示没有其他进程持有锁,这时将lock值设置为value,表示当前进程持有了锁 if(*lock == 0 && __sync_bool_compare_and_swap(lock, 0, value)){ return; } //如果是多处理器系统 if(sysconf(_SC_NPROCESSORS_CONF) > 1){ for (n = 1; n < spin; n <<= 1) { //随着等待的次数越来越多,实际去检查锁的间隔时间越来越大 for (i = 0; i < n; i++) { __asm__ ("pause"); } //检查锁是否被释放 if (*lock == 0 && __sync_bool_compare_and_swap(lock, 0, value)) { return; } } } //当前进程让出处理器,但仍然处于可执行状态 sched_yield(); } } /* void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin) { #if (NGX_HAVE_ATOMIC_OPS)//支持原子操作 ngx_uint_t i, n; //一直处于循环中,直到获取到锁 for ( ;; ) { //lock为0表示没有其他进程持有锁,这时将lock值设置为value参数表示当前进程持有了锁 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) { return; } //如果是多处理器系统 if (ngx_ncpu > 1) { for (n = 1; n < spin; n <<= 1) { //随着等待的次数越来越多,实际去检查锁的间隔时间越来越大 for (i = 0; i < n; i++) { ngx_cpu_pause();//告诉CPU现在处于自旋锁等待状态 } //检查锁是否被释放 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) { return; } } } //当前进程让出处理器,但仍然处于可执行状态 ngx_sched_yield(); } #else #if (NGX_THREADS) #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined ! #endif #endif } */ volatile unsigned long lock; int main() { fprintf(stderr,"cpu %d pid=%d\n",sysconf(_SC_NPROCESSORS_CONF),getpid()); my_spinlock(&lock,getpid(),1024); fprintf(stderr,"lock %d\n",lock); my_unlock(&lock); fprintf(stderr,"lock %d\n",lock); return 0; }