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