summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-02-06 17:13:34 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-02-06 17:13:34 +0000
commitf362ffa3807abff7ddf02a5444837d99e055118c (patch)
treefadacf8a1cfbb96801c55e8d68bb13d221849937 /sys/arch/i386
parent7db3ee67d9e72670d704be8f59c2fc3c4fe5684a (diff)
Add machine/atomic.h to all architectures and define two operations
right now that are supposed to be atomic with respect to interrupts and SMP: atomic_setbits_int and atomic_clearbits_int. All architectures other than i386 and amd64 get dummy implementations since at first we'll be replacing operations that are done with "a |= bit" and "a &= ~bit" today. More proper implementations will follow kettenis@, miod@ ok
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/include/atomic.h26
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/arch/i386/include/atomic.h b/sys/arch/i386/include/atomic.h
index a06878e87b0..baf3d7bde01 100644
--- a/sys/arch/i386/include/atomic.h
+++ b/sys/arch/i386/include/atomic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomic.h,v 1.3 2006/04/27 15:37:53 mickey Exp $ */
+/* $OpenBSD: atomic.h,v 1.4 2007/02/06 17:13:33 art Exp $ */
/* $NetBSD: atomic.h,v 1.1.2.2 2000/02/21 18:54:07 sommerfeld Exp $ */
/*-
@@ -42,11 +42,24 @@
#ifndef _ATOMIC_H_
#define _ATOMIC_H_
+/*
+ * Perform atomic operations on memory. Should be atomic with respect
+ * to interrupts and multiple processors.
+ *
+ * void atomic_setbits_int(volatile u_int *a, u_int mask) { *a |= mask; }
+ * void atomic_clearbits_int(volatile u_int *a, u_int mas) { *a &= ~mask; }
+ */
#ifndef _LOCORE
+#ifdef MULTIPROCESSOR
+#define LOCK "lock"
+#else
+#define LOCK
+#endif
+
static __inline u_int64_t
i386_atomic_testset_uq (volatile u_int64_t *ptr, u_int64_t val) {
- __asm__ volatile ("\n1:\tlock; cmpxchg8b (%1); jnz 1b" : "+A" (val) :
+ __asm__ volatile ("\n1:\t" LOCK " cmpxchg8b (%1); jnz 1b" : "+A" (val) :
"r" (ptr), "b" ((u_int32_t)val), "c" ((u_int32_t)(val >> 32)));
return val;
}
@@ -65,15 +78,20 @@ i386_atomic_testset_i (volatile int *ptr, unsigned long val) {
static __inline void
i386_atomic_setbits_l (volatile u_int32_t *ptr, unsigned long bits) {
- __asm __volatile("lock ; orl %1,%0" : "=m" (*ptr) : "ir" (bits));
+ __asm __volatile(LOCK " orl %1,%0" : "=m" (*ptr) : "ir" (bits));
}
static __inline void
i386_atomic_clearbits_l (volatile u_int32_t *ptr, unsigned long bits) {
bits = ~bits;
- __asm __volatile("lock ; and %1,%0" : "=m" (*ptr) : "ir" (bits));
+ __asm __volatile(LOCK " andl %1,%0" : "=m" (*ptr) : "ir" (bits));
}
+#define atomic_setbits_int i386_atomic_setbits_l
+#define atomic_clearbits_int i386_atomic_clearbits_l
+
+#undef LOCK
+
#endif
#endif