1 /* $OpenBSD: atomic.h,v 1.7 2011/03/23 16:54:37 pirofti Exp $ */ 2 /* 3 * Copyright (c) 2007 Artur Grabowski <art@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #ifndef _MACHINE_ATOMIC_H_ 19 #define _MACHINE_ATOMIC_H_ 20 21 #if defined(_KERNEL) 22 23 static __inline unsigned int 24 sparc64_cas(volatile unsigned int *uip, unsigned int expect, unsigned int new) 25 { 26 __asm __volatile("cas [%2], %3, %0" 27 : "+r" (new), "=m" (*uip) 28 : "r" (uip), "r" (expect), "m" (*uip)); 29 30 return (new); 31 } 32 33 static __inline unsigned long 34 sparc64_casx(volatile unsigned long *uip, unsigned long expect, 35 unsigned long new) 36 { 37 __asm __volatile("casx [%2], %3, %0" 38 : "+r" (new), "=m" (*uip) 39 : "r" (uip), "r" (expect), "m" (*uip)); 40 41 return (new); 42 } 43 44 static __inline void 45 atomic_setbits_int(volatile unsigned int *uip, unsigned int v) 46 { 47 volatile unsigned int e, r; 48 49 r = *uip; 50 do { 51 e = r; 52 r = sparc64_cas(uip, e, e | v); 53 } while (r != e); 54 } 55 56 static __inline void 57 atomic_clearbits_int(volatile unsigned int *uip, unsigned int v) 58 { 59 volatile unsigned int e, r; 60 61 r = *uip; 62 do { 63 e = r; 64 r = sparc64_cas(uip, e, e & ~v); 65 } while (r != e); 66 } 67 68 static __inline void 69 atomic_add_ulong(volatile unsigned long *ulp, unsigned long v) 70 { 71 volatile unsigned long e, r; 72 73 r = *ulp; 74 do { 75 e = r; 76 r = sparc64_casx(ulp, e, e + v); 77 } while (r != e); 78 } 79 80 #endif /* defined(_KERNEL) */ 81 #endif /* _MACHINE_ATOMIC_H_ */ 82