Mercurial > hg > nginx-vendor-0-5
comparison src/os/unix/ngx_atomic.h @ 44:4989c3d25945 NGINX_0_1_22
nginx 0.1.22
*) Bugfix: the ngx_http_stub_status_module showed incorrect handled
connections statistics if the proxying or FastCGI server were used.
*) Bugfix: the installation paths were incorrectly quoted on Linux and
Solaris; bug appeared in 0.1.21.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 22 Feb 2005 00:00:00 +0300 |
parents | 41ccba1aba45 |
children | 9f3205d496a0 |
comparison
equal
deleted
inserted
replaced
43:95fe5f51bcdb | 44:4989c3d25945 |
---|---|
14 | 14 |
15 #if ( __i386__ ) | 15 #if ( __i386__ ) |
16 | 16 |
17 #define NGX_HAVE_ATOMIC_OPS 1 | 17 #define NGX_HAVE_ATOMIC_OPS 1 |
18 | 18 |
19 typedef uint32_t ngx_atomic_int_t; | 19 typedef int32_t ngx_atomic_int_t; |
20 typedef volatile ngx_atomic_int_t ngx_atomic_t; | 20 typedef uint32_t ngx_atomic_uint_t; |
21 typedef volatile ngx_atomic_uint_t ngx_atomic_t; | |
21 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 | 22 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
22 | 23 |
23 | 24 |
24 #if (NGX_SMP) | 25 #if (NGX_SMP) |
25 #define NGX_SMP_LOCK "lock;" | 26 #define NGX_SMP_LOCK "lock;" |
29 | 30 |
30 /* | 31 /* |
31 * the "=q" is any of the %eax, %ebx, %ecx, or %edx registers. | 32 * the "=q" is any of the %eax, %ebx, %ecx, or %edx registers. |
32 * the '"0" (1)' parameter preloads 1 into %0. | 33 * the '"0" (1)' parameter preloads 1 into %0. |
33 * the "cc" means that flags were changed. | 34 * the "cc" means that flags were changed. |
35 * | |
36 * "xadd r, [m]": | |
37 * | |
38 * temp = [m]; | |
39 * [m] += r; | |
40 * r = temp; | |
34 */ | 41 */ |
35 | 42 |
36 static ngx_inline ngx_atomic_int_t | 43 static ngx_inline ngx_atomic_uint_t |
37 ngx_atomic_inc(ngx_atomic_t *value) | 44 ngx_atomic_inc(ngx_atomic_t *value) |
38 { | 45 { |
39 ngx_atomic_int_t old; | 46 ngx_atomic_uint_t old; |
40 | 47 |
41 __asm__ volatile ( | 48 __asm__ volatile ( |
42 | 49 |
43 NGX_SMP_LOCK | 50 NGX_SMP_LOCK |
44 " xaddl %0, %2; " | 51 " xaddl %0, %2; " |
48 | 55 |
49 return old; | 56 return old; |
50 } | 57 } |
51 | 58 |
52 | 59 |
53 static ngx_inline ngx_atomic_int_t | 60 static ngx_inline ngx_atomic_uint_t |
54 ngx_atomic_dec(ngx_atomic_t *value) | 61 ngx_atomic_dec(ngx_atomic_t *value) |
55 { | 62 { |
56 ngx_atomic_int_t old; | 63 ngx_atomic_uint_t old; |
57 | 64 |
58 __asm__ volatile ( | 65 __asm__ volatile ( |
59 | 66 |
60 NGX_SMP_LOCK | 67 NGX_SMP_LOCK |
61 " xaddl %0, %2; " | 68 " xaddl %0, %2; " |
72 * the "=a" and "a" are the %eax register. Although we can return result | 79 * the "=a" and "a" are the %eax register. Although we can return result |
73 * in any register, we use %eax because it is used in cmpxchg anyway. | 80 * in any register, we use %eax because it is used in cmpxchg anyway. |
74 * | 81 * |
75 * "cmpxchg r, [m]": | 82 * "cmpxchg r, [m]": |
76 * | 83 * |
77 * if (eax == [m]) { | 84 * if (eax == [m]) { |
78 * zf = 1; | 85 * zf = 1; |
79 * [m] = r; | 86 * [m] = r; |
80 * } else { | 87 * } else { |
81 * zf = 0; | 88 * zf = 0; |
82 * eax = [m]; | 89 * eax = [m]; |
83 * } | 90 * } |
84 */ | 91 */ |
85 | 92 |
86 static ngx_inline ngx_atomic_int_t | 93 static ngx_inline ngx_atomic_uint_t |
87 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old, | 94 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, |
88 ngx_atomic_int_t set) | 95 ngx_atomic_uint_t set) |
89 { | 96 { |
90 ngx_atomic_int_t res; | 97 ngx_atomic_uint_t res; |
91 | 98 |
92 __asm__ volatile ( | 99 __asm__ volatile ( |
93 | 100 |
94 NGX_SMP_LOCK | 101 NGX_SMP_LOCK |
95 " cmpxchgl %3, %1; " | 102 " cmpxchgl %3, %1; " |
105 #elif ( __amd64__ ) | 112 #elif ( __amd64__ ) |
106 | 113 |
107 #define NGX_HAVE_ATOMIC_OPS 1 | 114 #define NGX_HAVE_ATOMIC_OPS 1 |
108 | 115 |
109 typedef int64_t ngx_atomic_int_t; | 116 typedef int64_t ngx_atomic_int_t; |
110 typedef volatile ngx_atomic_int_t ngx_atomic_t; | 117 typedef uint64_t ngx_atomic_uint_t; |
118 typedef volatile ngx_atomic_uint_t ngx_atomic_t; | |
111 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 | 119 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 |
112 | 120 |
113 | 121 |
114 #if (NGX_SMP) | 122 #if (NGX_SMP) |
115 #define NGX_SMP_LOCK "lock;" | 123 #define NGX_SMP_LOCK "lock;" |
116 #else | 124 #else |
117 #define NGX_SMP_LOCK | 125 #define NGX_SMP_LOCK |
118 #endif | 126 #endif |
119 | 127 |
120 | 128 |
121 static ngx_inline ngx_atomic_int_t | 129 static ngx_inline ngx_atomic_uint_t |
122 ngx_atomic_inc(ngx_atomic_t *value) | 130 ngx_atomic_inc(ngx_atomic_t *value) |
123 { | 131 { |
124 ngx_atomic_int_t old; | 132 ngx_atomic_uint_t old; |
125 | 133 |
126 __asm__ volatile ( | 134 __asm__ volatile ( |
127 | 135 |
128 NGX_SMP_LOCK | 136 NGX_SMP_LOCK |
129 " xaddq %0, %2; " | 137 " xaddq %0, %2; " |
135 } | 143 } |
136 | 144 |
137 | 145 |
138 /* the '"0" (-1LL)' parameter preloads -1 into the 64-bit %0 register */ | 146 /* the '"0" (-1LL)' parameter preloads -1 into the 64-bit %0 register */ |
139 | 147 |
140 static ngx_inline ngx_atomic_int_t | 148 static ngx_inline ngx_atomic_uint_t |
141 ngx_atomic_dec(ngx_atomic_t *value) | 149 ngx_atomic_dec(ngx_atomic_t *value) |
142 { | 150 { |
143 ngx_atomic_int_t old; | 151 ngx_atomic_uint_t old; |
144 | 152 |
145 __asm__ volatile ( | 153 __asm__ volatile ( |
146 | 154 |
147 NGX_SMP_LOCK | 155 NGX_SMP_LOCK |
148 " xaddq %0, %2; " | 156 " xaddq %0, %2; " |
154 } | 162 } |
155 | 163 |
156 | 164 |
157 /* the "=a" and "a" are the %rax register. */ | 165 /* the "=a" and "a" are the %rax register. */ |
158 | 166 |
159 static ngx_inline ngx_atomic_int_t | 167 static ngx_inline ngx_atomic_uint_t |
160 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old, | 168 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, |
161 ngx_atomic_int_t set) | 169 ngx_atomic_uint_t set) |
162 { | 170 { |
163 ngx_atomic_int_t res; | 171 ngx_atomic_uint_t res; |
164 | 172 |
165 __asm__ volatile ( | 173 __asm__ volatile ( |
166 | 174 |
167 NGX_SMP_LOCK | 175 NGX_SMP_LOCK |
168 " cmpxchgq %3, %1; " | 176 " cmpxchgq %3, %1; " |
178 #elif ( __sparc__ ) | 186 #elif ( __sparc__ ) |
179 | 187 |
180 #define NGX_HAVE_ATOMIC_OPS 1 | 188 #define NGX_HAVE_ATOMIC_OPS 1 |
181 | 189 |
182 #if (NGX_PTR_SIZE == 8) | 190 #if (NGX_PTR_SIZE == 8) |
183 typedef uint64_t ngx_atomic_int_t; | 191 typedef int64_t ngx_atomic_int_t; |
192 typedef uint64_t ngx_atomic_uint_t; | |
184 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 | 193 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 |
185 #define NGX_CASXA "casxa" | 194 #define NGX_CASXA "casxa" |
186 #else | 195 #else |
187 typedef uint32_t ngx_atomic_int_t; | 196 typedef int32_t ngx_atomic_int_t; |
197 typedef uint32_t ngx_atomic_uint_t; | |
188 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 | 198 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
189 #define NGX_CASXA "casa" | 199 #define NGX_CASXA "casa" |
190 #endif | 200 #endif |
191 | 201 |
192 typedef volatile ngx_atomic_int_t ngx_atomic_t; | 202 typedef volatile ngx_atomic_uint_t ngx_atomic_t; |
193 | 203 |
194 | 204 |
195 /* | 205 /* |
196 * the "+r" means the general register used for both input and output. | 206 * the "+r" means the general register used for both input and output. |
197 * | 207 * |
205 * } | 215 * } |
206 * | 216 * |
207 * so "r0 == r2" means that the operation was successfull. | 217 * so "r0 == r2" means that the operation was successfull. |
208 */ | 218 */ |
209 | 219 |
210 static ngx_inline ngx_atomic_int_t | 220 static ngx_inline ngx_atomic_uint_t |
211 ngx_atomic_inc(ngx_atomic_t *value) | 221 ngx_atomic_inc(ngx_atomic_t *value) |
212 { | 222 { |
213 ngx_atomic_int_t old, new, res; | 223 ngx_atomic_uint_t old, new, res; |
214 | 224 |
215 old = *value; | 225 old = *value; |
216 | 226 |
217 for ( ;; ) { | 227 for ( ;; ) { |
218 | 228 |
232 old = res; | 242 old = res; |
233 } | 243 } |
234 } | 244 } |
235 | 245 |
236 | 246 |
237 static ngx_inline ngx_atomic_int_t | 247 static ngx_inline ngx_atomic_uint_t |
238 ngx_atomic_dec(ngx_atomic_t *value) | 248 ngx_atomic_dec(ngx_atomic_t *value) |
239 { | 249 { |
240 ngx_atomic_int_t old, new, res; | 250 ngx_atomic_uint_t old, new, res; |
241 | 251 |
242 old = *value; | 252 old = *value; |
243 | 253 |
244 for ( ;; ) { | 254 for ( ;; ) { |
245 | 255 |
259 old = res; | 269 old = res; |
260 } | 270 } |
261 } | 271 } |
262 | 272 |
263 | 273 |
264 static ngx_inline ngx_atomic_int_t | 274 static ngx_inline ngx_atomic_uint_t |
265 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old, ngx_atomic_int_t set) | 275 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, |
276 ngx_atomic_uint_t set) | |
266 { | 277 { |
267 __asm__ volatile ( | 278 __asm__ volatile ( |
268 | 279 |
269 NGX_CASXA " [%1] 0x80, %2, %0" | 280 NGX_CASXA " [%1] 0x80, %2, %0" |
270 | 281 |
277 #elif ( __ppc__ ) | 288 #elif ( __ppc__ ) |
278 | 289 |
279 #define NGX_HAVE_ATOMIC_OPS 1 | 290 #define NGX_HAVE_ATOMIC_OPS 1 |
280 | 291 |
281 #if (NGX_PTR_SIZE == 8) | 292 #if (NGX_PTR_SIZE == 8) |
282 typedef uint64_t ngx_atomic_int_t; | 293 typedef int64_t ngx_atomic_int_t; |
294 typedef uint64_t ngx_atomic_uint_t; | |
283 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 | 295 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 |
284 #else | 296 #else |
297 typedef int32_t ngx_atomic_int_t; | |
298 typedef uint32_t ngx_atomic_uint_t; | |
285 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 | 299 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 |
286 typedef uint32_t ngx_atomic_int_t; | |
287 #endif | 300 #endif |
288 | 301 |
289 typedef volatile ngx_atomic_int_t ngx_atomic_t; | 302 typedef volatile ngx_atomic_uint_t ngx_atomic_t; |
290 | 303 |
291 | 304 |
292 /* | 305 /* |
293 * the ppc assembler treats ";" as comment, so we have to use "\n". | 306 * the ppc assembler treats ";" as comment, so we have to use "\n". |
294 * the minus in "bne-" is a hint for the branch prediction unit that | 307 * the minus in "bne-" is a hint for the branch prediction unit that |
299 * except r0. the r0 register can not be used in "addi r0, r0, 1". | 312 * except r0. the r0 register can not be used in "addi r0, r0, 1". |
300 * the "1b" means the nearest backward label "1" and the "1f" means | 313 * the "1b" means the nearest backward label "1" and the "1f" means |
301 * the nearest forward label "1". | 314 * the nearest forward label "1". |
302 */ | 315 */ |
303 | 316 |
304 static ngx_inline ngx_atomic_int_t | 317 static ngx_inline ngx_atomic_uint_t |
305 ngx_atomic_inc(ngx_atomic_t *value) | 318 ngx_atomic_inc(ngx_atomic_t *value) |
306 { | 319 { |
307 ngx_atomic_int_t res; | 320 ngx_atomic_uint_t res; |
308 | 321 |
309 __asm__ volatile ( | 322 __asm__ volatile ( |
310 | 323 |
311 "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ | 324 "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ |
312 /* and store reservation */ | 325 /* and store reservation */ |
319 | 332 |
320 return res; | 333 return res; |
321 } | 334 } |
322 | 335 |
323 | 336 |
324 static ngx_inline ngx_atomic_int_t | 337 static ngx_inline ngx_atomic_uint_t |
325 ngx_atomic_dec(ngx_atomic_t *value) | 338 ngx_atomic_dec(ngx_atomic_t *value) |
326 { | 339 { |
327 ngx_atomic_int_t res; | 340 ngx_atomic_uint_t res; |
328 | 341 |
329 __asm__ volatile ( | 342 __asm__ volatile ( |
330 | 343 |
331 "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ | 344 "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ |
332 /* and store reservation */ | 345 /* and store reservation */ |
339 | 352 |
340 return res; | 353 return res; |
341 } | 354 } |
342 | 355 |
343 | 356 |
344 static ngx_inline ngx_atomic_int_t | 357 static ngx_inline ngx_atomic_uint_t |
345 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old, | 358 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, |
346 ngx_atomic_int_t set) | 359 ngx_atomic_uint_t set) |
347 { | 360 { |
348 ngx_atomic_int_t res, temp; | 361 ngx_atomic_uint_t res, temp; |
349 | 362 |
350 __asm__ volatile ( | 363 __asm__ volatile ( |
351 | 364 |
352 " li %0, 0 \n" /* preset "0" to "res" */ | 365 " li %0, 0 \n" /* preset "0" to "res" */ |
353 " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ | 366 " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ |
370 | 383 |
371 #else | 384 #else |
372 | 385 |
373 #define NGX_HAVE_ATOMIC_OPS 0 | 386 #define NGX_HAVE_ATOMIC_OPS 0 |
374 | 387 |
375 typedef uint32_t ngx_atomic_int_t; | 388 typedef int32_t ngx_atomic_int_t; |
376 typedef volatile ngx_atomic_int_t ngx_atomic_t; | 389 typedef uint32_t ngx_atomic_uint_t; |
390 typedef volatile ngx_atomic_uint_t ngx_atomic_t; | |
377 | 391 |
378 #define ngx_atomic_inc(x) ++(*(x)) | 392 #define ngx_atomic_inc(x) ++(*(x)) |
379 #define ngx_atomic_dec(x) --(*(x)) | 393 #define ngx_atomic_dec(x) --(*(x)) |
380 | 394 |
381 static ngx_inline ngx_atomic_int_t | 395 static ngx_inline ngx_atomic_uint_t |
382 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_int_t old, | 396 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, |
383 ngx_atomic_int_t set) | 397 ngx_atomic_uint_t set) |
384 { | 398 { |
385 *lock = set; | 399 *lock = set; |
386 return 1; | 400 return 1; |
387 } | 401 } |
388 | 402 |