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
|
110
|
90 /* the code in src/os/unix/ngx_sunpro_x86.il */
|
42
|
91
|
112
|
92 #define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
|
160
|
93 #define ngx_cpu_pause() __asm ("pause")
|
112
|
94
|
42
|
95
|
110
|
96 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
|
|
97
|
|
98 #define NGX_HAVE_ATOMIC_OPS 1
|
42
|
99
|
110
|
100 #include "ngx_gcc_atomic_x86.h"
|
42
|
101
|
110
|
102 #endif
|
42
|
103
|
|
104
|
96
|
105 #elif ( __amd64__ || __amd64 )
|
42
|
106
|
110
|
107 typedef int64_t ngx_atomic_int_t;
|
|
108 typedef uint64_t ngx_atomic_uint_t;
|
44
|
109 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
110
|
110 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
0
|
111
|
|
112
|
110
|
113 #if ( __SUNPRO_C )
|
0
|
114
|
110
|
115 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
116
|
110
|
117 ngx_atomic_uint_t
|
|
118 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
|
|
119 ngx_atomic_uint_t set);
|
0
|
120
|
110
|
121 ngx_atomic_int_t
|
|
122 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
|
0
|
123
|
110
|
124 /* the code in src/os/unix/ngx_sunpro_amd64.il */
|
0
|
125
|
112
|
126 #define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
|
160
|
127 #define ngx_cpu_pause() __asm ("pause")
|
112
|
128
|
0
|
129
|
110
|
130 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
|
0
|
131
|
110
|
132 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
133
|
110
|
134 #include "ngx_gcc_atomic_amd64.h"
|
0
|
135
|
110
|
136 #endif
|
0
|
137
|
|
138
|
96
|
139 #elif ( __sparc__ || __sparcv9 )
|
0
|
140
|
110
|
141 #if (NGX_PTR_SIZE == 8)
|
|
142
|
|
143 typedef int64_t ngx_atomic_int_t;
|
|
144 typedef uint64_t ngx_atomic_uint_t;
|
|
145 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
0
|
146
|
42
|
147 #else
|
110
|
148
|
|
149 typedef int32_t ngx_atomic_int_t;
|
|
150 typedef uint32_t ngx_atomic_uint_t;
|
|
151 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
|
152
|
42
|
153 #endif
|
|
154
|
44
|
155 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
0
|
156
|
|
157
|
110
|
158 #if ( __SUNPRO_C )
|
0
|
159
|
110
|
160 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
161
|
110
|
162 #include "ngx_sunpro_atomic_sparc64.h"
|
42
|
163
|
0
|
164
|
110
|
165 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
|
42
|
166
|
110
|
167 #define NGX_HAVE_ATOMIC_OPS 1
|
0
|
168
|
110
|
169 #include "ngx_gcc_atomic_sparc64.h"
|
0
|
170
|
110
|
171 #endif
|
42
|
172
|
|
173
|
162
|
174 #elif ( __powerpc__ || __POWERPC__ )
|
42
|
175
|
|
176 #define NGX_HAVE_ATOMIC_OPS 1
|
|
177
|
|
178 #if (NGX_PTR_SIZE == 8)
|
110
|
179
|
|
180 typedef int64_t ngx_atomic_int_t;
|
|
181 typedef uint64_t ngx_atomic_uint_t;
|
|
182 #define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
|
|
183
|
42
|
184 #else
|
110
|
185
|
|
186 typedef int32_t ngx_atomic_int_t;
|
|
187 typedef uint32_t ngx_atomic_uint_t;
|
|
188 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
|
189
|
42
|
190 #endif
|
|
191
|
44
|
192 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
42
|
193
|
|
194
|
110
|
195 #include "ngx_gcc_atomic_ppc.h"
|
42
|
196
|
|
197
|
110
|
198 #endif
|
42
|
199
|
270
|
200 #endif
|
|
201
|
42
|
202
|
110
|
203 #if !(NGX_HAVE_ATOMIC_OPS)
|
0
|
204
|
|
205 #define NGX_HAVE_ATOMIC_OPS 0
|
|
206
|
110
|
207 typedef int32_t ngx_atomic_int_t;
|
|
208 typedef uint32_t ngx_atomic_uint_t;
|
44
|
209 typedef volatile ngx_atomic_uint_t ngx_atomic_t;
|
110
|
210 #define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
|
0
|
211
|
|
212
|
44
|
213 static ngx_inline ngx_atomic_uint_t
|
|
214 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
|
|
215 ngx_atomic_uint_t set)
|
0
|
216 {
|
120
|
217 if (*lock == old) {
|
110
|
218 *lock = set;
|
|
219 return 1;
|
|
220 }
|
|
221
|
|
222 return 0;
|
|
223 }
|
|
224
|
|
225
|
|
226 static ngx_inline ngx_atomic_int_t
|
|
227 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
|
|
228 {
|
|
229 ngx_atomic_int_t old;
|
|
230
|
|
231 old = *value;
|
|
232 *value += add;
|
|
233
|
|
234 return old;
|
0
|
235 }
|
|
236
|
120
|
237 #define ngx_memory_barrier()
|
160
|
238 #define ngx_cpu_pause()
|
120
|
239
|
0
|
240 #endif
|
|
241
|
270
|
242
|
160
|
243 void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
|
0
|
244
|
|
245 #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
|
|
246 #define ngx_unlock(lock) *(lock) = 0
|
|
247
|
|
248
|
|
249 #endif /* _NGX_ATOMIC_H_INCLUDED_ */
|