|  |  | 
|  | /* | 
|  | * Copyright (C) Igor Sysoev | 
|  | */ | 
|  |  | 
|  |  | 
|  | #include <ngx_config.h> | 
|  | #include <ngx_core.h> | 
|  |  | 
|  |  | 
|  | 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 ( ;; ) { | 
|  |  | 
|  | 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(); | 
|  | } | 
|  |  | 
|  | 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 | 
|  |  | 
|  | } |