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
isc_atomic_xadd(isc_int32_t * p,isc_int32_t val)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
isc_atomic_xaddq(isc_int64_t * p,isc_int64_t val)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
isc_atomic_store(isc_int32_t * p,isc_int32_t val)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
isc_atomic_cmpxchg(isc_int32_t * p,isc_int32_t cmpval,isc_int32_t val)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