Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 1 | |
Igor Sysoev | d90282d | 2004-09-28 08:34:51 +0000 | [diff] [blame] | 2 | /* |
Igor Sysoev | ff8da91 | 2004-09-29 16:00:49 +0000 | [diff] [blame] | 3 | * Copyright (C) Igor Sysoev |
Igor Sysoev | d90282d | 2004-09-28 08:34:51 +0000 | [diff] [blame] | 4 | */ |
| 5 | |
| 6 | |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 7 | #include <ngx_config.h> |
| 8 | #include <ngx_core.h> |
| 9 | |
| 10 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 11 | void |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 12 | ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin) |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 13 | { |
Igor Sysoev | 85080d0 | 2004-09-22 16:18:21 +0000 | [diff] [blame] | 14 | |
| 15 | #if (NGX_HAVE_ATOMIC_OPS) |
| 16 | |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 17 | ngx_uint_t i, n; |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 18 | |
| 19 | for ( ;; ) { |
| 20 | |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 21 | if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) { |
| 22 | return; |
| 23 | } |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 24 | |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 25 | if (ngx_ncpu > 1) { |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 26 | |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 27 | for (n = 1; n < spin; n <<= 1) { |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 28 | |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 29 | for (i = 0; i < n; i++) { |
| 30 | ngx_cpu_pause(); |
| 31 | } |
| 32 | |
| 33 | if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) { |
| 34 | return; |
| 35 | } |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 36 | } |
| 37 | } |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 38 | |
| 39 | ngx_sched_yield(); |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 40 | } |
Igor Sysoev | 85080d0 | 2004-09-22 16:18:21 +0000 | [diff] [blame] | 41 | |
| 42 | #else |
| 43 | |
| 44 | #if (NGX_THREADS) |
| 45 | |
| 46 | #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined ! |
| 47 | |
| 48 | #endif |
| 49 | |
| 50 | #endif |
| 51 | |
Igor Sysoev | 078d1b2 | 2004-06-30 15:30:41 +0000 | [diff] [blame] | 52 | } |