diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-09-30 05:07:52 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-09-30 05:07:52 +0000 |
commit | 16d897ba3b0e21fdb7dc8bdbffe49188bac7e821 (patch) | |
tree | 42c759e4d9617aa9f9c5fbbba363261d05a030a8 | |
parent | 5357d3b9ea66cbe0e503753d0dcddd3737793753 (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@
-rw-r--r-- | sys/arch/sparc/include/atomic.h | 110 |
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; |