diff options
author | jhb <jhb@FreeBSD.org> | 2000-10-05 22:19:50 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-10-05 22:19:50 +0000 |
commit | 4cc9f87fa24c6b90c1d657b2704432cbea1b7bea (patch) | |
tree | 450dfcb1e8c87b4bdd8c5ff6f9366ee352c20736 /sys/i386 | |
parent | f1af81aa6915279026a28a9737be7ab17bfbf3e9 (diff) | |
download | FreeBSD-src-4cc9f87fa24c6b90c1d657b2704432cbea1b7bea.zip FreeBSD-src-4cc9f87fa24c6b90c1d657b2704432cbea1b7bea.tar.gz |
Add atomic_readandclear_int and atomic_readandclear_long.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/include/atomic.h | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index 35a710e..b38fd83 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/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_ */ |