xref: /minix/external/bsd/bind/include/isc/atomic.h (revision fb9c64b2)
1 /*	NetBSD: atomic.h,v 1.3 2010/12/25 15:26:32 christos Exp 	*/
2 
3 #ifndef ISC_ATOMIC_H
4 #define ISC_ATOMIC_H 1
5 
6 #ifdef ISC_PLATFORM_USETHREADS
7 #include <sys/atomic.h>
8 #else
9 #define ISC_NO_ATOMIC
10 #endif
11 #include <isc/types.h>
12 
13 /*
14  * This routine atomically increments the value stored in 'p' by 'val', and
15  * returns the previous value.
16  */
17 static __inline isc_int32_t
18 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
19 #ifdef ISC_NO_ATOMIC
20 	isc_int32_t oval = *p;
21 	*p += val;
22 	return oval;
23 #else
24 	return (isc_int32_t)atomic_add_32_nv((volatile uint32_t *)p,
25 	    (uint32_t)val) - val;
26 #endif
27 }
28 
29 #ifdef ISC_PLATFORM_HAVEXADDQ
30 static __inline isc_int64_t
31 isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
32 #ifdef ISC_NO_ATOMIC
33 	isc_int64_t oval = *p;
34 	*p += val;
35 	return oval;
36 #else
37 	return (isc_int64_t)atomic_add_64_nv((volatile uint64_t *)p,
38 	    (uint64_t)val) - val;
39 #endif
40 }
41 #endif
42 
43 /*
44  * This routine atomically stores the value 'val' in 'p'.
45  */
46 static __inline void
47 isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
48 #ifdef ISC_NO_ATOMIC
49 	*p = val;
50 #else
51 	(void)atomic_swap_32((volatile uint32_t *)p, (uint32_t)val);
52 #endif
53 }
54 
55 /*
56  * This routine atomically replaces the value in 'p' with 'val', if the
57  * original value is equal to 'cmpval'.  The original value is returned in any
58  * case.
59  */
60 static __inline__ isc_int32_t
61 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
62 #ifdef ISC_NO_ATOMIC
63 	isc_int32_t oval = *p;
64 	if (cmpval == oval)
65 		*p = val;
66 	return oval;
67 #else
68 	return (isc_int32_t) atomic_cas_32((volatile uint32_t *)p,
69 	    (uint32_t)cmpval, (uint32_t)val);
70 #endif
71 }
72 
73 #endif /* ISC_ATOMIC_H */
74