| |
| /* |
| * Copyright (C) Igor Sysoev |
| * Copyright (C) Nginx, Inc. |
| */ |
| |
| |
| #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 |
| |
| } |