comparison src/os/unix/ngx_atomic.h @ 495:fc9909c369b2 release-0.1.22

nginx-0.1.22-RELEASE import *) 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; the bug had appeared in 0.1.21.
author Igor Sysoev <igor@sysoev.ru>
date Thu, 24 Feb 2005 12:29:09 +0000
parents 975f62e77f02
children d7c90bb5ce83
comparison
equal deleted inserted replaced
494:f94c1b769a7c 495:fc9909c369b2
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