nxt_atomic.h (37:7ef020869079) nxt_atomic.h (2084:7d479274f334)
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#ifndef _NXT_ATOMIC_H_INCLUDED_
8#define _NXT_ATOMIC_H_INCLUDED_

--- 12 unchanged lines hidden (view full) ---

21typedef volatile nxt_atomic_uint_t nxt_atomic_t;
22
23/*
24 * __sync_bool_compare_and_swap() is a full barrier.
25 * __sync_lock_test_and_set() is an acquire barrier.
26 * __sync_lock_release() is a release barrier.
27 */
28
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#ifndef _NXT_ATOMIC_H_INCLUDED_
8#define _NXT_ATOMIC_H_INCLUDED_

--- 12 unchanged lines hidden (view full) ---

21typedef volatile nxt_atomic_uint_t nxt_atomic_t;
22
23/*
24 * __sync_bool_compare_and_swap() is a full barrier.
25 * __sync_lock_test_and_set() is an acquire barrier.
26 * __sync_lock_release() is a release barrier.
27 */
28
29#define \
30nxt_atomic_cmp_set(lock, cmp, set) \
29#define nxt_atomic_cmp_set(lock, cmp, set) \
31 __sync_bool_compare_and_swap(lock, cmp, set)
32
33
30 __sync_bool_compare_and_swap(lock, cmp, set)
31
32
34#define \
35nxt_atomic_xchg(lock, set) \
33#define nxt_atomic_xchg(lock, set) \
36 __sync_lock_test_and_set(lock, set)
37
38
34 __sync_lock_test_and_set(lock, set)
35
36
39#define \
40nxt_atomic_fetch_add(value, add) \
37#define nxt_atomic_fetch_add(value, add) \
41 __sync_fetch_and_add(value, add)
42
43
38 __sync_fetch_and_add(value, add)
39
40
44#define \
45nxt_atomic_try_lock(lock) \
41#define nxt_atomic_try_lock(lock) \
46 nxt_atomic_cmp_set(lock, 0, 1)
47
48
42 nxt_atomic_cmp_set(lock, 0, 1)
43
44
49#define \
50nxt_atomic_release(lock) \
45#define nxt_atomic_release(lock) \
51 __sync_lock_release(lock)
52
53
54#define nxt_atomic_or_fetch(ptr, val) \
55 __sync_or_and_fetch(ptr, val)
56
57
58#define nxt_atomic_and_fetch(ptr, val) \
59 __sync_and_and_fetch(ptr, val)
60
61
62#if (__i386__ || __i386 || __amd64__ || __amd64)
46 __sync_lock_release(lock)
47
48
49#define nxt_atomic_or_fetch(ptr, val) \
50 __sync_or_and_fetch(ptr, val)
51
52
53#define nxt_atomic_and_fetch(ptr, val) \
54 __sync_and_and_fetch(ptr, val)
55
56
57#if (__i386__ || __i386 || __amd64__ || __amd64)
63#define \
64nxt_cpu_pause() \
58#define nxt_cpu_pause() \
65 __asm__ ("pause")
66
67#else
59 __asm__ ("pause")
60
61#else
68#define \
69nxt_cpu_pause()
62#define nxt_cpu_pause()
70#endif
71
72
73#elif (NXT_HAVE_SOLARIS_ATOMIC) /* Solaris 10 */
74
75#include <atomic.h>
76
77typedef long nxt_atomic_int_t;
78typedef ulong_t nxt_atomic_uint_t;
79typedef volatile nxt_atomic_uint_t nxt_atomic_t;
80
81
63#endif
64
65
66#elif (NXT_HAVE_SOLARIS_ATOMIC) /* Solaris 10 */
67
68#include <atomic.h>
69
70typedef long nxt_atomic_int_t;
71typedef ulong_t nxt_atomic_uint_t;
72typedef volatile nxt_atomic_uint_t nxt_atomic_t;
73
74
82#define \
83nxt_atomic_cmp_set(lock, cmp, set) \
75#define nxt_atomic_cmp_set(lock, cmp, set) \
84 (atomic_cas_ulong(lock, cmp, set) == (ulong_t) cmp)
85
86
76 (atomic_cas_ulong(lock, cmp, set) == (ulong_t) cmp)
77
78
87#define \
88nxt_atomic_xchg(lock, set) \
79#define nxt_atomic_xchg(lock, set) \
89 atomic_add_swap(lock, set)
90
91
80 atomic_add_swap(lock, set)
81
82
92#define \
93nxt_atomic_fetch_add(value, add) \
83#define nxt_atomic_fetch_add(value, add) \
94 (atomic_add_long_nv(value, add) - add)
95
96
97#define nxt_atomic_or_fetch(ptr, val) \
98 atomic_or_ulong_nv(ptr, val)
99
100
101#define nxt_atomic_and_fetch(ptr, val) \

--- 17 unchanged lines hidden (view full) ---

119 *
120 * A release barrier requires at least #LoadStore and #StoreStore barriers,
121 * so a lock release does not require an explicit barrier: all load
122 * instructions in critical section is followed by implicit #LoadStore
123 * barrier and all store instructions are followed by implicit #StoreStore
124 * barrier.
125 */
126
84 (atomic_add_long_nv(value, add) - add)
85
86
87#define nxt_atomic_or_fetch(ptr, val) \
88 atomic_or_ulong_nv(ptr, val)
89
90
91#define nxt_atomic_and_fetch(ptr, val) \

--- 17 unchanged lines hidden (view full) ---

109 *
110 * A release barrier requires at least #LoadStore and #StoreStore barriers,
111 * so a lock release does not require an explicit barrier: all load
112 * instructions in critical section is followed by implicit #LoadStore
113 * barrier and all store instructions are followed by implicit #StoreStore
114 * barrier.
115 */
116
127#define \
128nxt_atomic_try_lock(lock) \
117#define nxt_atomic_try_lock(lock) \
129 nxt_atomic_cmp_set(lock, 0, 1)
130
131
118 nxt_atomic_cmp_set(lock, 0, 1)
119
120
132#define \
133nxt_atomic_release(lock) \
121#define nxt_atomic_release(lock) \
134 *lock = 0;
135
136
137/*
138 * The "rep; nop" is used instead of "pause" to omit the "[ PAUSE ]" hardware
139 * capability added by linker since Solaris ld.so.1 does not know about it:
140 *
141 * ld.so.1: ...: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
142 */
143
144#if (__i386__ || __i386 || __amd64__ || __amd64)
122 *lock = 0;
123
124
125/*
126 * The "rep; nop" is used instead of "pause" to omit the "[ PAUSE ]" hardware
127 * capability added by linker since Solaris ld.so.1 does not know about it:
128 *
129 * ld.so.1: ...: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
130 */
131
132#if (__i386__ || __i386 || __amd64__ || __amd64)
145#define \
146nxt_cpu_pause() \
133#define nxt_cpu_pause() \
147 __asm__ ("rep; nop")
148
149#else
134 __asm__ ("rep; nop")
135
136#else
150#define \
151nxt_cpu_pause()
137#define nxt_cpu_pause()
152#endif
153
154
155/* elif (NXT_HAVE_MACOSX_ATOMIC) */
156
157/*
158 * The atomic(3) interface has been introduced in MacOS 10.4 (Tiger) and
159 * extended in 10.5 (Leopard). However its support is omitted because:

--- 27 unchanged lines hidden (view full) ---

187 nxt_atomic_int_t old;
188
189 old = cmp;
190
191 return __compare_and_swaplp(lock, &old, set);
192}
193
194
138#endif
139
140
141/* elif (NXT_HAVE_MACOSX_ATOMIC) */
142
143/*
144 * The atomic(3) interface has been introduced in MacOS 10.4 (Tiger) and
145 * extended in 10.5 (Leopard). However its support is omitted because:

--- 27 unchanged lines hidden (view full) ---

173 nxt_atomic_int_t old;
174
175 old = cmp;
176
177 return __compare_and_swaplp(lock, &old, set);
178}
179
180
195#define \
196nxt_atomic_xchg(lock, set) \
181#define nxt_atomic_xchg(lock, set) \
197 __fetch_and_swaplp(lock, set)
198
199
182 __fetch_and_swaplp(lock, set)
183
184
200#define \
201nxt_atomic_fetch_add(value, add) \
185#define nxt_atomic_fetch_add(value, add) \
202 __fetch_and_addlp(value, add)
203
204
205#else /* NXT_32BIT */
206
207typedef int nxt_atomic_int_t;
208typedef unsigned int nxt_atomic_uint_t;
209typedef volatile nxt_atomic_int_t nxt_atomic_t;

--- 6 unchanged lines hidden (view full) ---

216 nxt_atomic_int_t old;
217
218 old = cmp;
219
220 return __compare_and_swap(lock, &old, set);
221}
222
223
186 __fetch_and_addlp(value, add)
187
188
189#else /* NXT_32BIT */
190
191typedef int nxt_atomic_int_t;
192typedef unsigned int nxt_atomic_uint_t;
193typedef volatile nxt_atomic_int_t nxt_atomic_t;

--- 6 unchanged lines hidden (view full) ---

200 nxt_atomic_int_t old;
201
202 old = cmp;
203
204 return __compare_and_swap(lock, &old, set);
205}
206
207
224#define \
225nxt_atomic_xchg(lock, set) \
208#define nxt_atomic_xchg(lock, set) \
226 __fetch_and_swap(lock, set)
227
228
209 __fetch_and_swap(lock, set)
210
211
229#define \
230nxt_atomic_fetch_add(value, add) \
212#define nxt_atomic_fetch_add(value, add) \
231 __fetch_and_add(value, add)
232
233
234#endif /* NXT_32BIT*/
235
236
237/*
238 * __lwsync() is a "lwsync" instruction that sets #LoadLoad, #LoadStore,

--- 26 unchanged lines hidden (view full) ---

265 __isync();
266 return 1;
267 }
268
269 return 0;
270}
271
272
213 __fetch_and_add(value, add)
214
215
216#endif /* NXT_32BIT*/
217
218
219/*
220 * __lwsync() is a "lwsync" instruction that sets #LoadLoad, #LoadStore,

--- 26 unchanged lines hidden (view full) ---

247 __isync();
248 return 1;
249 }
250
251 return 0;
252}
253
254
273#define \
274nxt_atomic_release(lock) \
255#define nxt_atomic_release(lock) \
275 do { __lwsync(); *lock = 0; } while (0)
276
277
256 do { __lwsync(); *lock = 0; } while (0)
257
258
278#define \
279nxt_cpu_pause()
259#define nxt_cpu_pause()
280
281
282#endif /* NXT_HAVE_XLC_ATOMIC */
283
284
285#endif /* _NXT_ATOMIC_H_INCLUDED_ */
260
261
262#endif /* NXT_HAVE_XLC_ATOMIC */
263
264
265#endif /* _NXT_ATOMIC_H_INCLUDED_ */