summaryrefslogtreecommitdiff
path: root/sys/arch/m68k/include
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-03-21 05:28:21 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-03-21 05:28:21 +0000
commitf3670beea1e30c96c45e286914486527148fa021 (patch)
treeb74937e19fa800cc91465dde8dfb36594b18a2a4 /sys/arch/m68k/include
parent87fecc3af24a298eaa93ca41a7ea4df73a49212f (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.h20
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) */