0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #ifndef _NGX_ATOMIC_H_INCLUDED_
|
|
8 #define _NGX_ATOMIC_H_INCLUDED_
|
|
9
|
|
10
|
|
11 #include <ngx_config.h>
|
|
12 #include <ngx_core.h>
|
|
13
|
|
14
|
270
|
15 #if (NGX_DARWIN_ATOMIC)
|
|
16
|
|
17 /*
|
|
18 * use Darwin 8 atomic(3) and barrier(3) operations
|
|
19 * optimized at run-time for UP and SMP
|
|
20 */
|
|
21
|
|
22 #include <libkern/OSAtomic.h>
|
|
23
|
|
24 /* "bool" conflicts with perl's CORE/handy.h
|
|
25 * "true" and "false" conflict with nginx, and of course we can rename them,
|
|
26 * but we need to undef "bool" anyway
|
|
27 */
|
|
28 #undef bool
|
|
29 #undef true
|
|
30 #undef false
|
|
31
|
|
32
|
|
33 #define NGX_HAVE_ATOMIC_OPS 1
|
|
34
|
|
35 #if (NGX_PTR_SIZE == 8)
|
|
36
|
|
37 typedef int64_t ngx_atomic_int_t;
|
|
38 typedef uint64_t ngx_atomic_uint_t;
|
|
39 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
|
40
|
|
41 #define ngx_atomic_cmp_set(lock, old, new) \
|
|
42 OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
|
|
43
|
|
44 #define ngx_atomic_fetch_add(value, add) \
|
|
45 (OSAtomicAdd64(add, (int64_t *) value) - add)
|
|
46
|
|
47 #else
|
|
48
|
|
49 typedef int32_t ngx_atomic_int_t;
|
|
50 typedef uint32_t ngx_atomic_uint_t;
|
|
51 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
|
52
|
|
53 #define ngx_atomic_cmp_set(lock, old, new) \
|
|
54 OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)
|
|
55
|
|
56 #define ngx_atomic_fetch_add(value, add) \
|
|
57 (OSAtomicAdd32(add, (int32_t *) value) - add)
|
|
58
|
|
59 #endif
|
|
60
|
|
61 #define ngx_memory_barrier() OSMemoryBarrier()
|
|
62
|
|
63 #define ngx_cpu_pause()
|
|
64
|
|
65 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
|
66
|
|
67
|
|
68 #else /* !(NGX_DARWIN) */
|
|
69
|
|
70
|
96
|
71 #if ( __i386__ || __i386 )
|
0
|
72
|
110
|
73 typedef int32_t ngx_atomic_int_t;
|
|
74 typedef uint32_t ngx_atomic_uint_t;
|
44
|
75 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
110
|
76 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
42
|
77
|
|
78
|
110
|
79 #if ( __SUNPRO_C )
|
42
|
80
|
110
|
81 #define NGX_HAVE_ATOMIC_OPS 1
|
42
|
82
|
110
|
83 ngx_atomic_uint_t
|
|
84 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
|
|
85 ngx_atomic_uint_t set);
|
42
|
86
|
110
|
87 ngx_atomic_int_t
|
|
88 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
|
42
|
89
|
320
|
90 /*
|
|
91 * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
|
|
92 * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_x86.il
|
|
93 */
|
|
94
|
|
95 void
|
|
96 ngx_cpu_pause(void);
|
|
97
|
110
|
98 /* the code in src/os/unix/ngx_sunpro_x86.il */
|
42
|
99
|
112
|
100 #define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
|
|
101
|
42
|
102
|
110
|
103 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
|
|
104
|
|
105 #define NGX_HAVE_ATOMIC_OPS 1
|
42
|
106
|
110
|
107 #include "ngx_gcc_atomic_x86.h"
|
42
|
108
|
110
|
109 #endif
|
42
|
110
|
|
111
|
96
|
112 #elif ( __amd64__ || __amd64 )
|
42
|
113
|
110
|
114 typedef int64_t ngx_atomic_int_t;
|
|
115 typedef uint64_t ngx_atomic_uint_t;
|
44
|
116 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
110
|
117 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
0
|
118
|
|
119
|
110
|
120 #if ( __SUNPRO_C )
|
0
|
121
|
110
|
122 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
123
|
110
|
124 ngx_atomic_uint_t
|
|
125 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
|
|
126 ngx_atomic_uint_t set);
|
0
|
127
|
110
|
128 ngx_atomic_int_t
|
|
129 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
|
0
|
130
|
320
|
131 /*
|
|
132 * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
|
|
133 * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_amd64.il
|
|
134 */
|
|
135
|
|
136 void
|
|
137 ngx_cpu_pause(void);
|
|
138
|
110
|
139 /* the code in src/os/unix/ngx_sunpro_amd64.il */
|
0
|
140
|
112
|
141 #define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
|
|
142
|
0
|
143
|
110
|
144 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
|
0
|
145
|
110
|
146 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
147
|
110
|
148 #include "ngx_gcc_atomic_amd64.h"
|
0
|
149
|
110
|
150 #endif
|
0
|
151
|
|
152
|
320
|
153 #elif ( __sparc__ || __sparc || __sparcv9 )
|
0
|
154
|
110
|
155 #if (NGX_PTR_SIZE == 8)
|
|
156
|
|
157 typedef int64_t ngx_atomic_int_t;
|
|
158 typedef uint64_t ngx_atomic_uint_t;
|
|
159 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
0
|
160
|
42
|
161 #else
|
110
|
162
|
|
163 typedef int32_t ngx_atomic_int_t;
|
|
164 typedef uint32_t ngx_atomic_uint_t;
|
|
165 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
|
166
|
42
|
167 #endif
|
|
168
|
44
|
169 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
0
|
170
|
|
171
|
110
|
172 #if ( __SUNPRO_C )
|
0
|
173
|
110
|
174 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
175
|
110
|
176 #include "ngx_sunpro_atomic_sparc64.h"
|
42
|
177
|
0
|
178
|
110
|
179 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
|
42
|
180
|
110
|
181 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
182
|
110
|
183 #include "ngx_gcc_atomic_sparc64.h"
|
0
|
184
|
110
|
185 #endif
|
42
|
186
|
|
187
|
162
|
188 #elif ( __powerpc__ || __POWERPC__ )
|
42
|
189
|
|
190 #define NGX_HAVE_ATOMIC_OPS 1
|
|
191
|
|
192 #if (NGX_PTR_SIZE == 8)
|
110
|
193
|
|
194 typedef int64_t ngx_atomic_int_t;
|
|
195 typedef uint64_t ngx_atomic_uint_t;
|
|
196 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
|
197
|
42
|
198 #else
|
110
|
199
|
|
200 typedef int32_t ngx_atomic_int_t;
|
|
201 typedef uint32_t ngx_atomic_uint_t;
|
|
202 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
|
203
|
42
|
204 #endif
|
|
205
|
44
|
206 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
42
|
207
|
|
208
|
110
|
209 #include "ngx_gcc_atomic_ppc.h"
|
42
|
210
|
|
211
|
110
|
212 #endif
|
42
|
213
|
270
|
214 #endif
|
|
215
|
42
|
216
|
110
|
217 #if !(NGX_HAVE_ATOMIC_OPS)
|
0
|
218
|
|
219 #define NGX_HAVE_ATOMIC_OPS 0
|
|
220
|
110
|
221 typedef int32_t ngx_atomic_int_t;
|
|
222 typedef uint32_t ngx_atomic_uint_t;
|
44
|
223 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
110
|
224 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
0
|
225
|
|
226
|
44
|
227 static ngx_inline ngx_atomic_uint_t
|
|
228 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
|
|
229 ngx_atomic_uint_t set)
|
0
|
230 {
|
120
|
231 if (*lock == old) {
|
110
|
232 *lock = set;
|
|
233 return 1;
|
|
234 }
|
|
235
|
|
236 return 0;
|
|
237 }
|
|
238
|
|
239
|
|
240 static ngx_inline ngx_atomic_int_t
|
|
241 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
|
|
242 {
|
|
243 ngx_atomic_int_t old;
|
|
244
|
|
245 old = *value;
|
|
246 *value += add;
|
|
247
|
|
248 return old;
|
0
|
249 }
|
|
250
|
120
|
251 #define ngx_memory_barrier()
|
160
|
252 #define ngx_cpu_pause()
|
120
|
253
|
0
|
254 #endif
|
|
255
|
270
|
256
|
160
|
257 void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
|
0
|
258
|
|
259 #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
|
|
260 #define ngx_unlock(lock) *(lock) = 0
|
|
261
|
|
262
|
|
263 #endif /* _NGX_ATOMIC_H_INCLUDED_ */
|