]> git.proxmox.com Git - mirror_zfs.git/blame - zfs/lib/libsolcompat/include/atomic.h
Remove stray stub kernel files which should be brought in my linux-kernel-module...
[mirror_zfs.git] / zfs / lib / libsolcompat / include / atomic.h
CommitLineData
34dc7c2f
BB
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _SYS_ATOMIC_H
28#define _SYS_ATOMIC_H
29
30
31
32#include <sys/types.h>
33#include <sys/inttypes.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39#if defined(_KERNEL) && defined(__GNUC__) && defined(_ASM_INLINES) && \
40 (defined(__i386) || defined(__amd64))
41#include <asm/atomic.h>
42#endif
43
44#if defined(_KERNEL) || defined(__STDC__)
45/*
46 * Increment target.
47 */
48extern void atomic_inc_8(volatile uint8_t *);
49extern void atomic_inc_uchar(volatile uchar_t *);
50extern void atomic_inc_16(volatile uint16_t *);
51extern void atomic_inc_ushort(volatile ushort_t *);
52extern void atomic_inc_32(volatile uint32_t *);
53extern void atomic_inc_uint(volatile uint_t *);
54extern void atomic_inc_ulong(volatile ulong_t *);
55#if defined(_KERNEL) || defined(_INT64_TYPE)
56extern void atomic_inc_64(volatile uint64_t *);
57#endif
58
59/*
60 * Decrement target
61 */
62extern void atomic_dec_8(volatile uint8_t *);
63extern void atomic_dec_uchar(volatile uchar_t *);
64extern void atomic_dec_16(volatile uint16_t *);
65extern void atomic_dec_ushort(volatile ushort_t *);
66extern void atomic_dec_32(volatile uint32_t *);
67extern void atomic_dec_uint(volatile uint_t *);
68extern void atomic_dec_ulong(volatile ulong_t *);
69#if defined(_KERNEL) || defined(_INT64_TYPE)
70extern void atomic_dec_64(volatile uint64_t *);
71#endif
72
73/*
74 * Add delta to target
75 */
76extern void atomic_add_8(volatile uint8_t *, int8_t);
77extern void atomic_add_char(volatile uchar_t *, signed char);
78extern void atomic_add_16(volatile uint16_t *, int16_t);
79extern void atomic_add_short(volatile ushort_t *, short);
80extern void atomic_add_32(volatile uint32_t *, int32_t);
81extern void atomic_add_int(volatile uint_t *, int);
82extern void atomic_add_ptr(volatile void *, ssize_t);
83extern void atomic_add_long(volatile ulong_t *, long);
84#if defined(_KERNEL) || defined(_INT64_TYPE)
85extern void atomic_add_64(volatile uint64_t *, int64_t);
86#endif
87
88/*
89 * logical OR bits with target
90 */
91extern void atomic_or_8(volatile uint8_t *, uint8_t);
92extern void atomic_or_uchar(volatile uchar_t *, uchar_t);
93extern void atomic_or_16(volatile uint16_t *, uint16_t);
94extern void atomic_or_ushort(volatile ushort_t *, ushort_t);
95extern void atomic_or_32(volatile uint32_t *, uint32_t);
96extern void atomic_or_uint(volatile uint_t *, uint_t);
97extern void atomic_or_ulong(volatile ulong_t *, ulong_t);
98#if defined(_KERNEL) || defined(_INT64_TYPE)
99extern void atomic_or_64(volatile uint64_t *, uint64_t);
100#endif
101
102/*
103 * logical AND bits with target
104 */
105extern void atomic_and_8(volatile uint8_t *, uint8_t);
106extern void atomic_and_uchar(volatile uchar_t *, uchar_t);
107extern void atomic_and_16(volatile uint16_t *, uint16_t);
108extern void atomic_and_ushort(volatile ushort_t *, ushort_t);
109extern void atomic_and_32(volatile uint32_t *, uint32_t);
110extern void atomic_and_uint(volatile uint_t *, uint_t);
111extern void atomic_and_ulong(volatile ulong_t *, ulong_t);
112#if defined(_KERNEL) || defined(_INT64_TYPE)
113extern void atomic_and_64(volatile uint64_t *, uint64_t);
114#endif
115
116/*
117 * As above, but return the new value. Note that these _nv() variants are
118 * substantially more expensive on some platforms than the no-return-value
119 * versions above, so don't use them unless you really need to know the
120 * new value *atomically* (e.g. when decrementing a reference count and
121 * checking whether it went to zero).
122 */
123
124/*
125 * Increment target and return new value.
126 */
127extern uint8_t atomic_inc_8_nv(volatile uint8_t *);
128extern uchar_t atomic_inc_uchar_nv(volatile uchar_t *);
129extern uint16_t atomic_inc_16_nv(volatile uint16_t *);
130extern ushort_t atomic_inc_ushort_nv(volatile ushort_t *);
131extern uint32_t atomic_inc_32_nv(volatile uint32_t *);
132extern uint_t atomic_inc_uint_nv(volatile uint_t *);
133extern ulong_t atomic_inc_ulong_nv(volatile ulong_t *);
134#if defined(_KERNEL) || defined(_INT64_TYPE)
135extern uint64_t atomic_inc_64_nv(volatile uint64_t *);
136#endif
137
138/*
139 * Decrement target and return new value.
140 */
141extern uint8_t atomic_dec_8_nv(volatile uint8_t *);
142extern uchar_t atomic_dec_uchar_nv(volatile uchar_t *);
143extern uint16_t atomic_dec_16_nv(volatile uint16_t *);
144extern ushort_t atomic_dec_ushort_nv(volatile ushort_t *);
145extern uint32_t atomic_dec_32_nv(volatile uint32_t *);
146extern uint_t atomic_dec_uint_nv(volatile uint_t *);
147extern ulong_t atomic_dec_ulong_nv(volatile ulong_t *);
148#if defined(_KERNEL) || defined(_INT64_TYPE)
149extern uint64_t atomic_dec_64_nv(volatile uint64_t *);
150#endif
151
152/*
153 * Add delta to target
154 */
155extern uint8_t atomic_add_8_nv(volatile uint8_t *, int8_t);
156extern uchar_t atomic_add_char_nv(volatile uchar_t *, signed char);
157extern uint16_t atomic_add_16_nv(volatile uint16_t *, int16_t);
158extern ushort_t atomic_add_short_nv(volatile ushort_t *, short);
159extern uint32_t atomic_add_32_nv(volatile uint32_t *, int32_t);
160extern uint_t atomic_add_int_nv(volatile uint_t *, int);
161extern void *atomic_add_ptr_nv(volatile void *, ssize_t);
162extern ulong_t atomic_add_long_nv(volatile ulong_t *, long);
163#if defined(_KERNEL) || defined(_INT64_TYPE)
164extern uint64_t atomic_add_64_nv(volatile uint64_t *, int64_t);
165#endif
166
167/*
168 * logical OR bits with target and return new value.
169 */
170extern uint8_t atomic_or_8_nv(volatile uint8_t *, uint8_t);
171extern uchar_t atomic_or_uchar_nv(volatile uchar_t *, uchar_t);
172extern uint16_t atomic_or_16_nv(volatile uint16_t *, uint16_t);
173extern ushort_t atomic_or_ushort_nv(volatile ushort_t *, ushort_t);
174extern uint32_t atomic_or_32_nv(volatile uint32_t *, uint32_t);
175extern uint_t atomic_or_uint_nv(volatile uint_t *, uint_t);
176extern ulong_t atomic_or_ulong_nv(volatile ulong_t *, ulong_t);
177#if defined(_KERNEL) || defined(_INT64_TYPE)
178extern uint64_t atomic_or_64_nv(volatile uint64_t *, uint64_t);
179#endif
180
181/*
182 * logical AND bits with target and return new value.
183 */
184extern uint8_t atomic_and_8_nv(volatile uint8_t *, uint8_t);
185extern uchar_t atomic_and_uchar_nv(volatile uchar_t *, uchar_t);
186extern uint16_t atomic_and_16_nv(volatile uint16_t *, uint16_t);
187extern ushort_t atomic_and_ushort_nv(volatile ushort_t *, ushort_t);
188extern uint32_t atomic_and_32_nv(volatile uint32_t *, uint32_t);
189extern uint_t atomic_and_uint_nv(volatile uint_t *, uint_t);
190extern ulong_t atomic_and_ulong_nv(volatile ulong_t *, ulong_t);
191#if defined(_KERNEL) || defined(_INT64_TYPE)
192extern uint64_t atomic_and_64_nv(volatile uint64_t *, uint64_t);
193#endif
194
195/*
196 * If *arg1 == arg2, set *arg1 = arg3; return old value
197 */
198extern uint8_t atomic_cas_8(volatile uint8_t *, uint8_t, uint8_t);
199extern uchar_t atomic_cas_uchar(volatile uchar_t *, uchar_t, uchar_t);
200extern uint16_t atomic_cas_16(volatile uint16_t *, uint16_t, uint16_t);
201extern ushort_t atomic_cas_ushort(volatile ushort_t *, ushort_t, ushort_t);
202extern uint32_t atomic_cas_32(volatile uint32_t *, uint32_t, uint32_t);
203extern uint_t atomic_cas_uint(volatile uint_t *, uint_t, uint_t);
204extern void *atomic_cas_ptr(volatile void *, void *, void *);
205extern ulong_t atomic_cas_ulong(volatile ulong_t *, ulong_t, ulong_t);
206#if defined(_KERNEL) || defined(_INT64_TYPE)
207extern uint64_t atomic_cas_64(volatile uint64_t *, uint64_t, uint64_t);
208#endif
209
210/*
211 * Swap target and return old value
212 */
213extern uint8_t atomic_swap_8(volatile uint8_t *, uint8_t);
214extern uchar_t atomic_swap_uchar(volatile uchar_t *, uchar_t);
215extern uint16_t atomic_swap_16(volatile uint16_t *, uint16_t);
216extern ushort_t atomic_swap_ushort(volatile ushort_t *, ushort_t);
217extern uint32_t atomic_swap_32(volatile uint32_t *, uint32_t);
218extern uint_t atomic_swap_uint(volatile uint_t *, uint_t);
219extern void *atomic_swap_ptr(volatile void *, void *);
220extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t);
221#if defined(_KERNEL) || defined(_INT64_TYPE)
222extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t);
223#endif
224
225/*
226 * Perform an exclusive atomic bit set/clear on a target.
227 * Returns 0 if bit was sucessfully set/cleared, or -1
228 * if the bit was already set/cleared.
229 */
230extern int atomic_set_long_excl(volatile ulong_t *, uint_t);
231extern int atomic_clear_long_excl(volatile ulong_t *, uint_t);
232
233/*
234 * Generic memory barrier used during lock entry, placed after the
235 * memory operation that acquires the lock to guarantee that the lock
236 * protects its data. No stores from after the memory barrier will
237 * reach visibility, and no loads from after the barrier will be
238 * resolved, before the lock acquisition reaches global visibility.
239 */
240extern void membar_enter(void);
241
242/*
243 * Generic memory barrier used during lock exit, placed before the
244 * memory operation that releases the lock to guarantee that the lock
245 * protects its data. All loads and stores issued before the barrier
246 * will be resolved before the subsequent lock update reaches visibility.
247 */
248extern void membar_exit(void);
249
250/*
251 * Arrange that all stores issued before this point in the code reach
252 * global visibility before any stores that follow; useful in producer
253 * modules that update a data item, then set a flag that it is available.
254 * The memory barrier guarantees that the available flag is not visible
255 * earlier than the updated data, i.e. it imposes store ordering.
256 */
257extern void membar_producer(void);
258
259/*
260 * Arrange that all loads issued before this point in the code are
261 * completed before any subsequent loads; useful in consumer modules
262 * that check to see if data is available and read the data.
263 * The memory barrier guarantees that the data is not sampled until
264 * after the available flag has been seen, i.e. it imposes load ordering.
265 */
266extern void membar_consumer(void);
267#endif
268
269#if !defined(_KERNEL) && !defined(__STDC__)
270extern void atomic_inc_8();
271extern void atomic_inc_uchar();
272extern void atomic_inc_16();
273extern void atomic_inc_ushort();
274extern void atomic_inc_32();
275extern void atomic_inc_uint();
276extern void atomic_inc_ulong();
277#if defined(_INT64_TYPE)
278extern void atomic_inc_64();
279#endif /* defined(_INT64_TYPE) */
280extern void atomic_dec_8();
281extern void atomic_dec_uchar();
282extern void atomic_dec_16();
283extern void atomic_dec_ushort();
284extern void atomic_dec_32();
285extern void atomic_dec_uint();
286extern void atomic_dec_ulong();
287#if defined(_INT64_TYPE)
288extern void atomic_dec_64();
289#endif /* defined(_INT64_TYPE) */
290extern void atomic_add_8();
291extern void atomic_add_char();
292extern void atomic_add_16();
293extern void atomic_add_short();
294extern void atomic_add_32();
295extern void atomic_add_int();
296extern void atomic_add_ptr();
297extern void atomic_add_long();
298#if defined(_INT64_TYPE)
299extern void atomic_add_64();
300#endif /* defined(_INT64_TYPE) */
301extern void atomic_or_8();
302extern void atomic_or_uchar();
303extern void atomic_or_16();
304extern void atomic_or_ushort();
305extern void atomic_or_32();
306extern void atomic_or_uint();
307extern void atomic_or_ulong();
308#if defined(_INT64_TYPE)
309extern void atomic_or_64();
310#endif /* defined(_INT64_TYPE) */
311extern void atomic_and_8();
312extern void atomic_and_uchar();
313extern void atomic_and_16();
314extern void atomic_and_ushort();
315extern void atomic_and_32();
316extern void atomic_and_uint();
317extern void atomic_and_ulong();
318#if defined(_INT64_TYPE)
319extern void atomic_and_64();
320#endif /* defined(_INT64_TYPE) */
321extern uint8_t atomic_inc_8_nv();
322extern uchar_t atomic_inc_uchar_nv();
323extern uint16_t atomic_inc_16_nv();
324extern ushort_t atomic_inc_ushort_nv();
325extern uint32_t atomic_inc_32_nv();
326extern uint_t atomic_inc_uint_nv();
327extern ulong_t atomic_inc_ulong_nv();
328#if defined(_INT64_TYPE)
329extern uint64_t atomic_inc_64_nv();
330#endif /* defined(_INT64_TYPE) */
331extern uint8_t atomic_dec_8_nv();
332extern uchar_t atomic_dec_uchar_nv();
333extern uint16_t atomic_dec_16_nv();
334extern ushort_t atomic_dec_ushort_nv();
335extern uint32_t atomic_dec_32_nv();
336extern uint_t atomic_dec_uint_nv();
337extern ulong_t atomic_dec_ulong_nv();
338#if defined(_INT64_TYPE)
339extern uint64_t atomic_dec_64_nv();
340#endif /* defined(_INT64_TYPE) */
341extern uint8_t atomic_add_8_nv();
342extern uchar_t atomic_add_char_nv();
343extern uint16_t atomic_add_16_nv();
344extern ushort_t atomic_add_short_nv();
345extern uint32_t atomic_add_32_nv();
346extern uint_t atomic_add_int_nv();
347extern void *atomic_add_ptr_nv();
348extern ulong_t atomic_add_long_nv();
349#if defined(_INT64_TYPE)
350extern uint64_t atomic_add_64_nv();
351#endif /* defined(_INT64_TYPE) */
352extern uint8_t atomic_or_8_nv();
353extern uchar_t atomic_or_uchar_nv();
354extern uint16_t atomic_or_16_nv();
355extern ushort_t atomic_or_ushort_nv();
356extern uint32_t atomic_or_32_nv();
357extern uint_t atomic_or_uint_nv();
358extern ulong_t atomic_or_ulong_nv();
359#if defined(_INT64_TYPE)
360extern uint64_t atomic_or_64_nv();
361#endif /* defined(_INT64_TYPE) */
362extern uint8_t atomic_and_8_nv();
363extern uchar_t atomic_and_uchar_nv();
364extern uint16_t atomic_and_16_nv();
365extern ushort_t atomic_and_ushort_nv();
366extern uint32_t atomic_and_32_nv();
367extern uint_t atomic_and_uint_nv();
368extern ulong_t atomic_and_ulong_nv();
369#if defined(_INT64_TYPE)
370extern uint64_t atomic_and_64_nv();
371#endif /* defined(_INT64_TYPE) */
372extern uint8_t atomic_cas_8();
373extern uchar_t atomic_cas_uchar();
374extern uint16_t atomic_cas_16();
375extern ushort_t atomic_cas_ushort();
376extern uint32_t atomic_cas_32();
377extern uint_t atomic_cas_uint();
378extern void *atomic_cas_ptr();
379extern ulong_t atomic_cas_ulong();
380#if defined(_INT64_TYPE)
381extern uint64_t atomic_cas_64();
382#endif /* defined(_INT64_TYPE) */
383extern uint8_t atomic_swap_8();
384extern uchar_t atomic_swap_uchar();
385extern uint16_t atomic_swap_16();
386extern ushort_t atomic_swap_ushort();
387extern uint32_t atomic_swap_32();
388extern uint_t atomic_swap_uint();
389extern void *atomic_swap_ptr();
390extern ulong_t atomic_swap_ulong();
391#if defined(_INT64_TYPE)
392extern uint64_t atomic_swap_64();
393#endif /* defined(_INT64_TYPE) */
394
395
396extern int atomic_set_long_excl();
397extern int atomic_clear_long_excl();
398
399extern void membar_enter();
400extern void membar_exit();
401extern void membar_producer();
402extern void membar_consumer();
403
404#endif
405
406#if defined(_KERNEL)
407
408#if defined(_LP64) || defined(_ILP32)
409#define atomic_add_ip atomic_add_long
410#define atomic_add_ip_nv atomic_add_long_nv
411#define casip atomic_cas_ulong
412#endif
413
414#if defined(__sparc)
415extern uint8_t ldstub(uint8_t *);
416#endif
417
418/*
419 * Legacy kernel interfaces; they will go away (eventually).
420 */
421extern uint8_t cas8(uint8_t *, uint8_t, uint8_t);
422extern uint32_t cas32(uint32_t *, uint32_t, uint32_t);
423extern uint64_t cas64(uint64_t *, uint64_t, uint64_t);
424extern ulong_t caslong(ulong_t *, ulong_t, ulong_t);
425extern void *casptr(void *, void *, void *);
426extern void atomic_and_long(ulong_t *, ulong_t);
427extern void atomic_or_long(ulong_t *, ulong_t);
428#if defined(__sparc)
429extern uint32_t swapl(uint32_t *, uint32_t);
430#endif
431
432#endif /* _KERNEL */
433
434#ifdef __cplusplus
435}
436#endif
437
438#endif /* _SYS_ATOMIC_H */