summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include/atomic.h
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2000-10-05 22:19:50 +0000
committerjhb <jhb@FreeBSD.org>2000-10-05 22:19:50 +0000
commit4cc9f87fa24c6b90c1d657b2704432cbea1b7bea (patch)
tree450dfcb1e8c87b4bdd8c5ff6f9366ee352c20736 /sys/amd64/include/atomic.h
parentf1af81aa6915279026a28a9737be7ab17bfbf3e9 (diff)
downloadFreeBSD-src-4cc9f87fa24c6b90c1d657b2704432cbea1b7bea.zip
FreeBSD-src-4cc9f87fa24c6b90c1d657b2704432cbea1b7bea.tar.gz
Add atomic_readandclear_int and atomic_readandclear_long.
Diffstat (limited to 'sys/amd64/include/atomic.h')
-rw-r--r--sys/amd64/include/atomic.h36
1 files changed, 34 insertions, 2 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index 35a710e..b38fd83 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -46,11 +46,13 @@
* atomic_clear_int(P, V) (*(u_int*)(P) &= ~(V))
* atomic_add_int(P, V) (*(u_int*)(P) += (V))
* atomic_subtract_int(P, V) (*(u_int*)(P) -= (V))
+ * atomic_readandclear_int(P) (return *(u_int*)P; *(u_int*)P = 0;)
*
* atomic_set_long(P, V) (*(u_long*)(P) |= (V))
* atomic_clear_long(P, V) (*(u_long*)(P) &= ~(V))
* atomic_add_long(P, V) (*(u_long*)(P) += (V))
* atomic_subtract_long(P, V) (*(u_long*)(P) -= (V))
+ * atomic_readandclear_long(P) (return *(u_long*)P; *(u_long*)P = 0;)
*/
/*
@@ -63,9 +65,9 @@
*/
#if defined(KLD_MODULE)
#define ATOMIC_ASM(NAME, TYPE, OP, V) \
- extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v);
+ void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v);
-extern int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
+int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
#else /* !KLD_MODULE */
#if defined(SMP)
@@ -218,6 +220,36 @@ atomic_cmpset_ptr(volatile void *dst, void *exp, void *src)
return (
atomic_cmpset_int((volatile u_int *)dst, (u_int)exp, (u_int)src));
}
+
+static __inline u_int
+atomic_readandclear_int(volatile u_int *addr)
+{
+ u_int result;
+
+ __asm __volatile (
+ " xorl %0,%0 ; "
+ " xchgl %1,%0 ; "
+ "# atomic_readandclear_int"
+ : "=&r" (result) /* 0 (result) */
+ : "m" (*addr)); /* 1 (addr) */
+
+ return (result);
+}
+
+static __inline u_long
+atomic_readandclear_long(volatile u_long *addr)
+{
+ u_long result;
+
+ __asm __volatile (
+ " xorl %0,%0 ; "
+ " xchgl %1,%0 ; "
+ "# atomic_readandclear_int"
+ : "=&r" (result) /* 0 (result) */
+ : "m" (*addr)); /* 1 (addr) */
+
+ return (result);
+}
#endif
#endif /* ! _MACHINE_ATOMIC_H_ */
OpenPOWER on IntegriCloud