xref: /openbsd/sys/arch/sparc64/include/atomic.h (revision cca36db2)
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