Mercurial > hg > nginx
annotate src/core/ngx_shmtx.c @ 4450:4919fb357a5d stable-1.0
Merge of r4406, r4413: copyrights updated.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 05 Feb 2012 20:02:59 +0000 |
parents | 0daede16d68b |
children |
rev | line source |
---|---|
611 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4450
4919fb357a5d
Merge of r4406, r4413: copyrights updated.
Maxim Dounin <mdounin@mdounin.ru>
parents:
3909
diff
changeset
|
4 * Copyright (C) Nginx, Inc. |
611 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 | |
11 | |
12 #if (NGX_HAVE_ATOMIC_OPS) | |
13 | |
14 | |
15 ngx_int_t | |
860
201d017ea470
slab allocator in shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
611
diff
changeset
|
16 ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name) |
611 | 17 { |
18 mtx->lock = addr; | |
19 | |
3909
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
20 if (mtx->spin == (ngx_uint_t) -1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
21 return NGX_OK; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
22 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
23 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
24 mtx->spin = 2048; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
25 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
26 #if (NGX_HAVE_POSIX_SEM) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
27 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
28 if (sem_init(&mtx->sem, 1, 0) == -1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
29 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
30 "sem_init() failed"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
31 } else { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
32 mtx->semaphore = 1; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
33 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
34 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
35 #endif |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
36 |
611 | 37 return NGX_OK; |
38 } | |
39 | |
3909
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
40 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
41 void |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
42 ngx_shmtx_destory(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
43 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
44 #if (NGX_HAVE_POSIX_SEM) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
45 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
46 if (mtx->semaphore) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
47 if (sem_destroy(&mtx->sem) == -1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
48 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
49 "sem_destroy() failed"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
50 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
51 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
52 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
53 #endif |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
54 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
55 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
56 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
57 ngx_uint_t |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
58 ngx_shmtx_trylock(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
59 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
60 ngx_atomic_uint_t val; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
61 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
62 val = *mtx->lock; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
63 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
64 return ((val & 0x80000000) == 0 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
65 && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000)); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
66 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
67 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
68 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
69 void |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
70 ngx_shmtx_lock(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
71 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
72 ngx_uint_t i, n; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
73 ngx_atomic_uint_t val; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
74 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
75 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx lock"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
76 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
77 for ( ;; ) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
78 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
79 val = *mtx->lock; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
80 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
81 if ((val & 0x80000000) == 0 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
82 && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000)) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
83 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
84 return; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
85 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
86 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
87 if (ngx_ncpu > 1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
88 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
89 for (n = 1; n < mtx->spin; n <<= 1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
90 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
91 for (i = 0; i < n; i++) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
92 ngx_cpu_pause(); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
93 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
94 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
95 val = *mtx->lock; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
96 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
97 if ((val & 0x80000000) == 0 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
98 && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000)) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
99 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
100 return; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
101 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
102 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
103 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
104 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
105 #if (NGX_HAVE_POSIX_SEM) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
106 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
107 if (mtx->semaphore) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
108 val = *mtx->lock; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
109 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
110 if ((val & 0x80000000) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
111 && ngx_atomic_cmp_set(mtx->lock, val, val + 1)) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
112 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
113 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
114 "shmtx wait %XA", val); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
115 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
116 while (sem_wait(&mtx->sem) == -1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
117 ngx_err_t err; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
118 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
119 err = ngx_errno; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
120 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
121 if (err != NGX_EINTR) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
122 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
123 "sem_wait() failed while waiting on shmtx"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
124 break; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
125 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
126 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
127 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
128 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
129 "shmtx awoke"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
130 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
131 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
132 continue; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
133 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
134 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
135 #endif |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
136 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
137 ngx_sched_yield(); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
138 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
139 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
140 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
141 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
142 void |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
143 ngx_shmtx_unlock(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
144 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
145 ngx_atomic_uint_t val, old, wait; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
146 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
147 if (mtx->spin != (ngx_uint_t) -1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
148 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx unlock"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
149 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
150 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
151 for ( ;; ) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
152 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
153 old = *mtx->lock; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
154 wait = old & 0x7fffffff; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
155 val = wait ? wait - 1 : 0; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
156 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
157 if (ngx_atomic_cmp_set(mtx->lock, old, val)) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
158 break; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
159 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
160 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
161 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
162 #if (NGX_HAVE_POSIX_SEM) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
163 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
164 if (wait == 0 || !mtx->semaphore) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
165 return; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
166 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
167 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
168 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
169 "shmtx wake %XA", old); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
170 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
171 if (sem_post(&mtx->sem) == -1) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
172 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
173 "sem_post() failed while wake shmtx"); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
174 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
175 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
176 #endif |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
177 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
178 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
179 |
611 | 180 #else |
181 | |
182 | |
183 ngx_int_t | |
860
201d017ea470
slab allocator in shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
611
diff
changeset
|
184 ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name) |
611 | 185 { |
186 if (mtx->name) { | |
187 | |
188 if (ngx_strcmp(name, mtx->name) == 0) { | |
189 mtx->name = name; | |
190 return NGX_OK; | |
191 } | |
192 | |
193 ngx_shmtx_destory(mtx); | |
194 } | |
195 | |
1100
01884449985f
fix building on platforms with non-supported atomic operations
Igor Sysoev <igor@sysoev.ru>
parents:
860
diff
changeset
|
196 mtx->fd = ngx_open_file(name, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN, |
01884449985f
fix building on platforms with non-supported atomic operations
Igor Sysoev <igor@sysoev.ru>
parents:
860
diff
changeset
|
197 NGX_FILE_DEFAULT_ACCESS); |
611 | 198 |
199 if (mtx->fd == NGX_INVALID_FILE) { | |
860
201d017ea470
slab allocator in shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
611
diff
changeset
|
200 ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, |
611 | 201 ngx_open_file_n " \"%s\" failed", name); |
202 return NGX_ERROR; | |
203 } | |
204 | |
205 if (ngx_delete_file(name) == NGX_FILE_ERROR) { | |
860
201d017ea470
slab allocator in shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
611
diff
changeset
|
206 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
611 | 207 ngx_delete_file_n " \"%s\" failed", name); |
208 } | |
209 | |
210 mtx->name = name; | |
211 | |
212 return NGX_OK; | |
213 } | |
214 | |
215 | |
216 void | |
217 ngx_shmtx_destory(ngx_shmtx_t *mtx) | |
218 { | |
219 if (ngx_close_file(mtx->fd) == NGX_FILE_ERROR) { | |
860
201d017ea470
slab allocator in shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
611
diff
changeset
|
220 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
611 | 221 ngx_close_file_n " \"%s\" failed", mtx->name); |
222 } | |
223 } | |
224 | |
225 | |
3909
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
226 ngx_uint_t |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
227 ngx_shmtx_trylock(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
228 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
229 ngx_err_t err; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
230 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
231 err = ngx_trylock_fd(mtx->fd); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
232 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
233 if (err == 0) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
234 return 1; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
235 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
236 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
237 if (err == NGX_EAGAIN) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
238 return 0; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
239 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
240 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
241 #if __osf__ /* Tru64 UNIX */ |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
242 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
243 if (err == NGX_EACCESS) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
244 return 0; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
245 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
246 |
611 | 247 #endif |
3909
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
248 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
249 ngx_log_abort(err, ngx_trylock_fd_n " %s failed", mtx->name); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
250 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
251 return 0; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
252 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
253 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
254 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
255 void |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
256 ngx_shmtx_lock(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
257 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
258 ngx_err_t err; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
259 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
260 err = ngx_lock_fd(mtx->fd); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
261 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
262 if (err == 0) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
263 return; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
264 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
265 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
266 ngx_log_abort(err, ngx_lock_fd_n " %s failed", mtx->name); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
267 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
268 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
269 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
270 void |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
271 ngx_shmtx_unlock(ngx_shmtx_t *mtx) |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
272 { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
273 ngx_err_t err; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
274 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
275 err = ngx_unlock_fd(mtx->fd); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
276 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
277 if (err == 0) { |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
278 return; |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
279 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
280 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
281 ngx_log_abort(err, ngx_unlock_fd_n " %s failed", mtx->name); |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
282 } |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
283 |
0daede16d68b
use POSIX semaphores in shmtx instead of sched_yield()
Igor Sysoev <igor@sysoev.ru>
parents:
1100
diff
changeset
|
284 #endif |