summaryrefslogtreecommitdiff
path: root/sys/arch/sparc
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-09-30 05:07:52 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-09-30 05:07:52 +0000
commit16d897ba3b0e21fdb7dc8bdbffe49188bac7e821 (patch)
tree42c759e4d9617aa9f9c5fbbba363261d05a030a8 /sys/arch/sparc
parent5357d3b9ea66cbe0e503753d0dcddd3737793753 (diff)
implement the atomic_shizz(9) bits.
sparc lacks cool opcodes, but is only uniprocessor, so these are done with simple critical sections. tested by miod@ bcook@ ok miod@
Diffstat (limited to 'sys/arch/sparc')
-rw-r--r--sys/arch/sparc/include/atomic.h110
1 files changed, 107 insertions, 3 deletions
diff --git a/sys/arch/sparc/include/atomic.h b/sys/arch/sparc/include/atomic.h
index 5c3d0cb4b04..b567c09d381 100644
--- a/sys/arch/sparc/include/atomic.h
+++ b/sys/arch/sparc/include/atomic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomic.h,v 1.6 2014/03/29 18:09:30 guenther Exp $ */
+/* $OpenBSD: atomic.h,v 1.7 2014/09/30 05:07:51 dlg Exp $ */
/* Public Domain */
@@ -9,7 +9,111 @@
#include <machine/psl.h>
-static __inline void
+static inline unsigned int
+_atomic_cas_word(volatile unsigned int *uip, unsigned int o, unsigned int n)
+{
+ int psr;
+ unsigned int rv;
+
+ psr = getpsr();
+ setpsr(psr | PSR_PIL);
+ rv = *uip;
+ if (rv == o)
+ *uip = n;
+ setpsr(psr);
+
+ return (rv);
+}
+#define atomic_cas_uint(_p, _o, _n) _atomic_cas_word((_p), (_o), (_n))
+#define atomic_cas_ulong(_p, _o, _n) _atomic_cas_word((_p), (_o), (_n))
+
+static inline void *
+_atomic_cas_ptr(volatile void *uip, void *o, void *n)
+{
+ int psr;
+ void * volatile *uipp = (void * volatile *)uip;
+ void *rv;
+
+ psr = getpsr();
+ setpsr(psr | PSR_PIL);
+ rv = *uipp;
+ if (rv == o)
+ *uipp = n;
+ setpsr(psr);
+
+ return (rv);
+}
+#define atomic_cas_ptr(_p, _o, _n) _atomic_cas_ptr((_p), (_o), (_n))
+
+static inline unsigned int
+_atomic_swap_word(volatile unsigned int *uip, unsigned int n)
+{
+ int psr;
+ unsigned int rv;
+
+ psr = getpsr();
+ setpsr(psr | PSR_PIL);
+ rv = *uip;
+ *uip = n;
+ setpsr(psr);
+
+ return (rv);
+}
+#define atomic_swap_uint(_p, _n) _atomic_swap_word((_p), (_n))
+#define atomic_swap_ulong(_p, _n) _atomic_swap_word((_p), (_n))
+
+static inline void *
+_atomic_swap_ptr(volatile void *uip, void *n)
+{
+ int psr;
+ void * volatile *uipp = (void * volatile *)uip;
+ void *rv;
+
+ psr = getpsr();
+ setpsr(psr | PSR_PIL);
+ rv = *uipp;
+ *uipp = n;
+ setpsr(psr);
+
+ return (rv);
+}
+#define atomic_swap_ptr(_p, _o, _n) _atomic_swap_ptr((_p), (_o), (_n))
+
+static inline unsigned int
+_atomic_add_word_nv(volatile unsigned int *uip, unsigned int v)
+{
+ int psr;
+ unsigned int rv;
+
+ psr = getpsr();
+ setpsr(psr | PSR_PIL);
+ rv = *uip + v;
+ *uip = rv;
+ setpsr(psr);
+
+ return (rv);
+}
+#define atomic_add_int_nv(_p, _v) _atomic_add_word_nv((_p), (_v))
+#define atomic_add_long_nv(_p, _v) _atomic_add_word_nv((_p), (_v))
+
+static inline unsigned int
+_atomic_sub_word_nv(volatile unsigned int *uip, unsigned int v)
+{
+ int psr;
+ unsigned int rv;
+
+ psr = getpsr();
+ setpsr(psr | PSR_PIL);
+ rv = *uip - v;
+ *uip = rv;
+ setpsr(psr);
+
+ return (rv);
+}
+#define atomic_sub_int_nv(_p, _v) _atomic_sub_word_nv((_p), (_v))
+#define atomic_sub_long_nv(_p, _v) _atomic_sub_word_nv((_p), (_v))
+
+static inline void
atomic_setbits_int(volatile unsigned int *uip, unsigned int v)
{
int psr;
@@ -20,7 +124,7 @@ atomic_setbits_int(volatile unsigned int *uip, unsigned int v)
setpsr(psr);
}
-static __inline void
+static inline void
atomic_clearbits_int(volatile unsigned int *uip, unsigned int v)
{
int psr;