Mercurial > hg > nginx
annotate src/os/unix/ngx_atomic.h @ 525:09b42134ac0c release-0.1.37
nginx-0.1.37-RELEASE import
*) Change: now the "\n" is added to the end of the "nginx.pid" file.
*) Bugfix: the responses may be transferred not completely, if many
parts or the big parts were included by SSI.
*) Bugfix: if all backends had returned the 404 reponse and the
"http_404" parameter of the "proxy_next_upstream" or
"fastcgi_next_upstream" directives was used, then nginx started to
request all backends again.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 23 Jun 2005 13:41:06 +0000 |
parents | d7c90bb5ce83 |
children | 818fbd4750b9 |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
435
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
435
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
435
diff
changeset
|
4 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
435
diff
changeset
|
5 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
435
diff
changeset
|
6 |
212
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 #ifndef _NGX_ATOMIC_H_INCLUDED_ |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #define _NGX_ATOMIC_H_INCLUDED_ |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 #include <ngx_config.h> |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
12 #include <ngx_core.h> |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
13 |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
14 |
493 | 15 #if ( __i386__ ) |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
16 |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
17 #define NGX_HAVE_ATOMIC_OPS 1 |
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
18 |
495 | 19 typedef int32_t ngx_atomic_int_t; |
20 typedef uint32_t ngx_atomic_uint_t; | |
21 typedef volatile ngx_atomic_uint_t ngx_atomic_t; | |
493 | 22 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
23 | |
24 | |
25 #if (NGX_SMP) | |
26 #define NGX_SMP_LOCK "lock;" | |
27 #else | |
28 #define NGX_SMP_LOCK | |
29 #endif | |
30 | |
31 /* | |
32 * the "=q" is any of the %eax, %ebx, %ecx, or %edx registers. | |
33 * the '"0" (1)' parameter preloads 1 into %0. | |
34 * the "cc" means that flags were changed. | |
495 | 35 * |
36 * "xadd r, [m]": | |
37 * | |
38 * temp = [m]; | |
39 * [m] += r; | |
40 * r = temp; | |
493 | 41 */ |
42 | |
495 | 43 static ngx_inline ngx_atomic_uint_t |
493 | 44 ngx_atomic_inc(ngx_atomic_t *value) |
45 { | |
495 | 46 ngx_atomic_uint_t old; |
493 | 47 |
48 __asm__ volatile ( | |
49 | |
50 NGX_SMP_LOCK | |
51 " xaddl %0, %2; " | |
52 " incl %0; " | |
53 | |
54 : "=q" (old) : "0" (1), "m" (*value) : "cc", "memory"); | |
55 | |
56 return old; | |
57 } | |
58 | |
59 | |
495 | 60 static ngx_inline ngx_atomic_uint_t |
493 | 61 ngx_atomic_dec(ngx_atomic_t *value) |
62 { | |
495 | 63 ngx_atomic_uint_t old; |
493 | 64 |
65 __asm__ volatile ( | |
66 | |
67 NGX_SMP_LOCK | |
68 " xaddl %0, %2; " | |
69 " decl %0; " | |
70 | |
71 : "=q" (old) : "0" (-1), "m" (*value) : "cc", "memory"); | |
72 | |
73 return old; | |
74 } | |
75 | |
76 | |
77 /* | |
78 * the "q" is any of the %eax, %ebx, %ecx, or %edx registers. | |
79 * the "=a" and "a" are the %eax register. Although we can return result | |
80 * in any register, we use %eax because it is used in cmpxchg anyway. | |
81 * | |
82 * "cmpxchg r, [m]": | |
83 * | |
495 | 84 * if (eax == [m]) { |
85 * zf = 1; | |
86 * [m] = r; | |
87 * } else { | |
88 * zf = 0; | |
89 * eax = [m]; | |
90 * } | |
493 | 91 */ |
92 | |
495 | 93 static ngx_inline ngx_atomic_uint_t |
94 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, | |
95 ngx_atomic_uint_t set) | |
493 | 96 { |
495 | 97 ngx_atomic_uint_t res; |
493 | 98 |
99 __asm__ volatile ( | |
100 | |
101 NGX_SMP_LOCK | |
102 " cmpxchgl %3, %1; " | |
103 " setz %b0; " | |
104 " movzbl %b0, %0; " | |
105 | |
106 : "=a" (res) : "m" (*lock), "a" (old), "q" (set) : "cc", "memory"); | |
107 | |
108 return res; | |
109 } | |
110 | |
111 | |
112 #elif ( __amd64__ ) | |
113 | |
114 #define NGX_HAVE_ATOMIC_OPS 1 | |
115 | |
116 typedef int64_t ngx_atomic_int_t; | |
495 | 117 typedef uint64_t ngx_atomic_uint_t; |
118 typedef volatile ngx_atomic_uint_t ngx_atomic_t; | |
493 | 119 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 |
120 | |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
121 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
122 #if (NGX_SMP) |
300
502b03d9d2a3
nginx-0.0.3-2004-03-31-00:31:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
299
diff
changeset
|
123 #define NGX_SMP_LOCK "lock;" |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
124 #else |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
125 #define NGX_SMP_LOCK |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
126 #endif |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
127 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
128 |
495 | 129 static ngx_inline ngx_atomic_uint_t |
493 | 130 ngx_atomic_inc(ngx_atomic_t *value) |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
131 { |
495 | 132 ngx_atomic_uint_t old; |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
133 |
267
83205e0b5522
nginx-0.0.2-2004-02-24-20:31:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
266
diff
changeset
|
134 __asm__ volatile ( |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
135 |
493 | 136 NGX_SMP_LOCK |
137 " xaddq %0, %2; " | |
138 " incq %0; " | |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
139 |
493 | 140 : "=r" (old) : "0" (1), "m" (*value) : "cc", "memory"); |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
141 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
142 return old; |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
143 } |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
144 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
145 |
493 | 146 /* the '"0" (-1LL)' parameter preloads -1 into the 64-bit %0 register */ |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
147 |
495 | 148 static ngx_inline ngx_atomic_uint_t |
493 | 149 ngx_atomic_dec(ngx_atomic_t *value) |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
150 { |
495 | 151 ngx_atomic_uint_t old; |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
152 |
267
83205e0b5522
nginx-0.0.2-2004-02-24-20:31:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
266
diff
changeset
|
153 __asm__ volatile ( |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
154 |
493 | 155 NGX_SMP_LOCK |
156 " xaddq %0, %2; " | |
157 " decq %0; " | |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
158 |
493 | 159 : "=r" (old) : "0" (-1LL), "m" (*value) : "cc", "memory"); |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
160 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
161 return old; |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
162 } |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
163 |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
164 |
493 | 165 /* the "=a" and "a" are the %rax register. */ |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
166 |
495 | 167 static ngx_inline ngx_atomic_uint_t |
168 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, | |
169 ngx_atomic_uint_t set) | |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
170 { |
495 | 171 ngx_atomic_uint_t res; |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
172 |
267
83205e0b5522
nginx-0.0.2-2004-02-24-20:31:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
266
diff
changeset
|
173 __asm__ volatile ( |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
174 |
493 | 175 NGX_SMP_LOCK |
176 " cmpxchgq %3, %1; " | |
177 " setz %b0; " | |
178 " movzbq %b0, %0; " | |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
179 |
493 | 180 : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory"); |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
181 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
182 return res; |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
183 } |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
184 |
301
744965ec6275
nginx-0.0.3-2004-03-31-19:26:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
300
diff
changeset
|
185 |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
186 #elif ( __sparc__ ) |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
187 |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
188 #define NGX_HAVE_ATOMIC_OPS 1 |
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
189 |
493 | 190 #if (NGX_PTR_SIZE == 8) |
495 | 191 typedef int64_t ngx_atomic_int_t; |
192 typedef uint64_t ngx_atomic_uint_t; | |
493 | 193 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 |
194 #define NGX_CASXA "casxa" | |
195 #else | |
495 | 196 typedef int32_t ngx_atomic_int_t; |
197 typedef uint32_t ngx_atomic_uint_t; | |
493 | 198 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
199 #define NGX_CASXA "casa" | |
200 #endif | |
201 | |
495 | 202 typedef volatile ngx_atomic_uint_t ngx_atomic_t; |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
203 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
204 |
493 | 205 /* |
206 * the "+r" means the general register used for both input and output. | |
207 * | |
208 * "casa [r1] 0x80, r2, r0" and | |
209 * "casxa [r1] 0x80, r2, r0" do the following: | |
210 * | |
211 * if ([r1] == r2) { | |
212 * swap(r0, [r1]); | |
213 * } else { | |
214 * r0 = [r1]; | |
215 * } | |
216 * | |
217 * so "r0 == r2" means that the operation was successfull. | |
218 */ | |
219 | |
495 | 220 static ngx_inline ngx_atomic_uint_t |
493 | 221 ngx_atomic_inc(ngx_atomic_t *value) |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
222 { |
495 | 223 ngx_atomic_uint_t old, new, res; |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
224 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
225 old = *value; |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
226 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
227 for ( ;; ) { |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
228 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
229 new = old + 1; |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
230 res = new; |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
231 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
232 __asm__ volatile ( |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
233 |
493 | 234 NGX_CASXA " [%1] 0x80, %2, %0" |
235 | |
236 : "+r" (res) : "r" (value), "r" (old) : "memory"); | |
237 | |
238 if (res == old) { | |
239 return new; | |
240 } | |
241 | |
242 old = res; | |
243 } | |
244 } | |
245 | |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
246 |
495 | 247 static ngx_inline ngx_atomic_uint_t |
493 | 248 ngx_atomic_dec(ngx_atomic_t *value) |
249 { | |
495 | 250 ngx_atomic_uint_t old, new, res; |
493 | 251 |
252 old = *value; | |
253 | |
254 for ( ;; ) { | |
255 | |
256 new = old - 1; | |
257 res = new; | |
258 | |
259 __asm__ volatile ( | |
260 | |
261 NGX_CASXA " [%1] 0x80, %2, %0" | |
262 | |
263 : "+r" (res) : "r" (value), "r" (old) : "memory"); | |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
264 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
265 if (res == old) { |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
266 return new; |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
267 } |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
268 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
269 old = res; |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
270 } |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
271 } |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
272 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
273 |
495 | 274 static ngx_inline ngx_atomic_uint_t |
275 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, | |
276 ngx_atomic_uint_t set) | |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
277 { |
493 | 278 __asm__ volatile ( |
279 | |
280 NGX_CASXA " [%1] 0x80, %2, %0" | |
281 | |
282 : "+r" (set) : "r" (lock), "r" (old) : "memory"); | |
283 | |
284 return (set == old); | |
285 } | |
286 | |
287 | |
525 | 288 #elif ( __ppc__ || __powerpc__ ) |
493 | 289 |
290 #define NGX_HAVE_ATOMIC_OPS 1 | |
291 | |
292 #if (NGX_PTR_SIZE == 8) | |
495 | 293 typedef int64_t ngx_atomic_int_t; |
294 typedef uint64_t ngx_atomic_uint_t; | |
493 | 295 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 |
296 #else | |
495 | 297 typedef int32_t ngx_atomic_int_t; |
298 typedef uint32_t ngx_atomic_uint_t; | |
493 | 299 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
300 #endif | |
301 | |
495 | 302 typedef volatile ngx_atomic_uint_t ngx_atomic_t; |
493 | 303 |
304 | |
305 /* | |
306 * the ppc assembler treats ";" as comment, so we have to use "\n". | |
307 * the minus in "bne-" is a hint for the branch prediction unit that | |
308 * this branch is unlikely to be taken. | |
309 * | |
310 * the "=&r" means that no input registers can be used. | |
311 * the "=&b" means that the base registers can be used only, i.e. any register | |
312 * except r0. the r0 register can not be used in "addi r0, r0, 1". | |
313 * the "1b" means the nearest backward label "1" and the "1f" means | |
314 * the nearest forward label "1". | |
315 */ | |
316 | |
495 | 317 static ngx_inline ngx_atomic_uint_t |
493 | 318 ngx_atomic_inc(ngx_atomic_t *value) |
319 { | |
495 | 320 ngx_atomic_uint_t res; |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
321 |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
322 __asm__ volatile ( |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
323 |
493 | 324 "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ |
325 /* and store reservation */ | |
326 " addi %0, %0, 1 \n" /* add "1" to "res" */ | |
327 " stwcx. %0, 0, %1 \n" /* store "res" into [value] if reservation */ | |
328 /* is not cleared */ | |
329 " bne- 1b \n" /* try again if reservation was cleared */ | |
330 | |
331 : "=&b" (res) : "r" (value) : "cc", "memory"); | |
332 | |
333 return res; | |
334 } | |
335 | |
336 | |
495 | 337 static ngx_inline ngx_atomic_uint_t |
493 | 338 ngx_atomic_dec(ngx_atomic_t *value) |
339 { | |
495 | 340 ngx_atomic_uint_t res; |
493 | 341 |
342 __asm__ volatile ( | |
343 | |
344 "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ | |
345 /* and store reservation */ | |
346 " addi %0, %0, -1 \n" /* sub "1" from "res" */ | |
347 " stwcx. %0, 0, %1 \n" /* store "res" into [value] if reservation */ | |
348 /* is not cleared */ | |
349 " bne- 1b \n" /* try again if reservation was cleared */ | |
350 | |
351 : "=&b" (res) : "r" (value) : "cc", "memory"); | |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
352 |
493 | 353 return res; |
354 } | |
355 | |
356 | |
495 | 357 static ngx_inline ngx_atomic_uint_t |
358 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, | |
359 ngx_atomic_uint_t set) | |
493 | 360 { |
495 | 361 ngx_atomic_uint_t res, temp; |
493 | 362 |
363 __asm__ volatile ( | |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
364 |
493 | 365 " li %0, 0 \n" /* preset "0" to "res" */ |
366 " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ | |
367 /* and store reservation */ | |
368 " cmpw %1, %3 \n" /* compare "temp" and "old" */ | |
369 " bne- 1f \n" /* not equal */ | |
370 " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ | |
371 /* is not cleared */ | |
372 " bne- 1f \n" /* the reservation was cleared */ | |
373 " li %0, 1 \n" /* set "1" to "res" */ | |
374 "1: \n" | |
375 | |
376 : "=&r" (res), "=&r" (temp) | |
377 : "r" (lock), "r" (old), "r" (set) | |
378 : "cc", "memory"); | |
379 | |
380 return res; | |
425
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
381 } |
bd39260a1383
nginx-0.0.10-2004-09-14-19:55:24 import
Igor Sysoev <igor@sysoev.ru>
parents:
373
diff
changeset
|
382 |
493 | 383 |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
384 #else |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
385 |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
386 #define NGX_HAVE_ATOMIC_OPS 0 |
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
387 |
495 | 388 typedef int32_t ngx_atomic_int_t; |
389 typedef uint32_t ngx_atomic_uint_t; | |
390 typedef volatile ngx_atomic_uint_t ngx_atomic_t; | |
497 | 391 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
392 |
493 | 393 #define ngx_atomic_inc(x) ++(*(x)) |
394 #define ngx_atomic_dec(x) --(*(x)) | |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
395 |
495 | 396 static ngx_inline ngx_atomic_uint_t |
397 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, | |
398 ngx_atomic_uint_t set) | |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
399 { |
493 | 400 *lock = set; |
435
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
401 return 1; |
5cdc4838d4e8
nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
433
diff
changeset
|
402 } |
266
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
403 |
5238e93961a1
nginx-0.0.2-2004-02-23-23:57:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
213
diff
changeset
|
404 #endif |
212
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
405 |
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
406 |
373
018569a8f09c
nginx-0.0.7-2004-06-30-19:30:41 import
Igor Sysoev <igor@sysoev.ru>
parents:
371
diff
changeset
|
407 void ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin); |
018569a8f09c
nginx-0.0.7-2004-06-30-19:30:41 import
Igor Sysoev <igor@sysoev.ru>
parents:
371
diff
changeset
|
408 |
371
780e93985b93
nginx-0.0.7-2004-06-28-20:05:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
370
diff
changeset
|
409 #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) |
780e93985b93
nginx-0.0.7-2004-06-28-20:05:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
370
diff
changeset
|
410 #define ngx_unlock(lock) *(lock) = 0 |
370
54f76b0b8dca
nginx-0.0.7-2004-06-27-22:01:57 import
Igor Sysoev <igor@sysoev.ru>
parents:
302
diff
changeset
|
411 |
54f76b0b8dca
nginx-0.0.7-2004-06-27-22:01:57 import
Igor Sysoev <igor@sysoev.ru>
parents:
302
diff
changeset
|
412 |
212
679f60139863
nginx-0.0.1-2003-12-19-11:15:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
413 #endif /* _NGX_ATOMIC_H_INCLUDED_ */ |