diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-21 05:28:21 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-21 05:28:21 +0000 |
commit | f3670beea1e30c96c45e286914486527148fa021 (patch) | |
tree | b74937e19fa800cc91465dde8dfb36594b18a2a4 /sys/arch/m68k/include | |
parent | 87fecc3af24a298eaa93ca41a7ea4df73a49212f (diff) |
Real atomic_{set,clear}bits_int implementation, no performance hit on 060
unless used on non-aligned data; ok deraadt@
Diffstat (limited to 'sys/arch/m68k/include')
-rw-r--r-- | sys/arch/m68k/include/atomic.h | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/arch/m68k/include/atomic.h b/sys/arch/m68k/include/atomic.h index 712302d48d8..9a411d7d0b8 100644 --- a/sys/arch/m68k/include/atomic.h +++ b/sys/arch/m68k/include/atomic.h @@ -1,4 +1,4 @@ -/* $OpenBSD: atomic.h,v 1.2 2007/02/19 17:18:43 deraadt Exp $ */ +/* $OpenBSD: atomic.h,v 1.3 2007/03/21 05:28:20 miod Exp $ */ /* Public Domain */ @@ -10,13 +10,27 @@ static __inline void atomic_setbits_int(__volatile unsigned int *uip, unsigned int v) { - *uip |= v; + unsigned int witness, old, new; + + do { + witness = old = *uip; + new = old | v; + __asm__ __volatile__ ( + "casl %0, %2, %1" : "+d"(old), "=m"(*uip) : "d"(new)); + } while (old != witness); } static __inline void atomic_clearbits_int(__volatile unsigned int *uip, unsigned int v) { - *uip &= ~v; + unsigned int witness, old, new; + + do { + witness = old = *uip; + new = old & ~v; + __asm__ __volatile__ ( + "casl %0, %2, %1" : "+d"(old), "=m"(*uip) : "d"(new)); + } while (old != witness); } #endif /* defined(_KERNEL) */ |