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