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