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