svn commit: r253874 - in projects/atomic64/sys: amd64/include i386/include
Jung-uk Kim
jkim at FreeBSD.org
Thu Aug 1 23:38:58 UTC 2013
Author: jkim
Date: Thu Aug 1 23:38:57 2013
New Revision: 253874
URL: http://svnweb.freebsd.org/changeset/base/253874
Log:
Add a new atomic operation atomic_swap for x86. This operation atomically
loads the current value and stores a new value at once, i. e.,
tmp = *p; *p = v; return (tmp);
Note atomic_readandclear is now obsolete and reimplemented as a macro around
atomic_swap where the new value v is zero.
Modified:
projects/atomic64/sys/amd64/include/atomic.h
projects/atomic64/sys/i386/include/atomic.h
Modified: projects/atomic64/sys/amd64/include/atomic.h
==============================================================================
--- projects/atomic64/sys/amd64/include/atomic.h Thu Aug 1 23:38:30 2013 (r253873)
+++ projects/atomic64/sys/amd64/include/atomic.h Thu Aug 1 23:38:57 2013 (r253874)
@@ -54,12 +54,14 @@
* 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_swap_int(P, V) (return (*(u_int *)(P)); *(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_swap_long(P, V) (return (*(u_long *)(P)); *(u_long *)(P) = (V);)
* atomic_readandclear_long(P) (return (*(u_long *)(P)); *(u_long *)(P) = 0;)
*/
@@ -301,45 +303,39 @@ ATOMIC_STORE(long);
#ifndef WANT_FUNCTIONS
-/* Read the current value and store a zero in the destination. */
+/* Read the current value and store a new value in the destination. */
#ifdef __GNUCLIKE_ASM
static __inline u_int
-atomic_readandclear_int(volatile u_int *addr)
+atomic_swap_int(volatile u_int *p, u_int v)
{
- u_int res;
- res = 0;
__asm __volatile(
- " xchgl %1,%0 ; "
- "# atomic_readandclear_int"
- : "+r" (res), /* 0 */
- "=m" (*addr) /* 1 */
- : "m" (*addr));
-
- return (res);
+ " xchgl %1, %0 ; "
+ "# atomic_swap_int"
+ : "+r" (v), /* 0 */
+ "=m" (*p) /* 1 */
+ : "m" (*p));
+ return (v);
}
static __inline u_long
-atomic_readandclear_long(volatile u_long *addr)
+atomic_swap_long(volatile u_long *p, u_long v)
{
- u_long res;
- res = 0;
__asm __volatile(
- " xchgq %1,%0 ; "
- "# atomic_readandclear_long"
- : "+r" (res), /* 0 */
- "=m" (*addr) /* 1 */
- : "m" (*addr));
-
- return (res);
+ " xchgq %1, %0 ; "
+ "# atomic_swap_long"
+ : "+r" (v), /* 0 */
+ "=m" (*p) /* 1 */
+ : "m" (*p));
+ return (v);
}
#else /* !__GNUCLIKE_ASM */
-u_int atomic_readandclear_int(volatile u_int *addr);
-u_long atomic_readandclear_long(volatile u_long *addr);
+u_int atomic_swap_int(volatile u_int *, u_int);
+u_long atomic_swap_long(volatile u_long *, u_long);
#endif /* __GNUCLIKE_ASM */
@@ -383,6 +379,9 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_acq_long atomic_cmpset_long
#define atomic_cmpset_rel_long atomic_cmpset_long
+#define atomic_readandclear_int(p) atomic_swap_int(p, 0)
+#define atomic_readandclear_long(p) atomic_swap_long(p, 0)
+
/* Operations on 8-bit bytes. */
#define atomic_set_8 atomic_set_char
#define atomic_set_acq_8 atomic_set_acq_char
@@ -433,6 +432,7 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_32 atomic_cmpset_int
#define atomic_cmpset_acq_32 atomic_cmpset_acq_int
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
+#define atomic_swap_32 atomic_swap_int
#define atomic_readandclear_32 atomic_readandclear_int
#define atomic_fetchadd_32 atomic_fetchadd_int
@@ -454,6 +454,7 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_64 atomic_cmpset_long
#define atomic_cmpset_acq_64 atomic_cmpset_acq_long
#define atomic_cmpset_rel_64 atomic_cmpset_rel_long
+#define atomic_swap_64 atomic_swap_long
#define atomic_readandclear_64 atomic_readandclear_long
/* Operations on pointers. */
@@ -474,6 +475,7 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_ptr atomic_cmpset_long
#define atomic_cmpset_acq_ptr atomic_cmpset_acq_long
#define atomic_cmpset_rel_ptr atomic_cmpset_rel_long
+#define atomic_swap_ptr atomic_swap_long
#define atomic_readandclear_ptr atomic_readandclear_long
#endif /* !WANT_FUNCTIONS */
Modified: projects/atomic64/sys/i386/include/atomic.h
==============================================================================
--- projects/atomic64/sys/i386/include/atomic.h Thu Aug 1 23:38:30 2013 (r253873)
+++ projects/atomic64/sys/i386/include/atomic.h Thu Aug 1 23:38:57 2013 (r253874)
@@ -54,12 +54,14 @@
* 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_swap_int(P, V) (return (*(u_int *)(P)); *(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_swap_long(P, V) (return (*(u_long *)(P)); *(u_long *)(P) = (V);)
* atomic_readandclear_long(P) (return (*(u_long *)(P)); *(u_long *)(P) = 0;)
*/
@@ -392,45 +394,33 @@ atomic_fetchadd_long(volatile u_long *p,
return (atomic_fetchadd_int((volatile u_int *)p, (u_int)v));
}
-/* Read the current value and store a zero in the destination. */
+/* Read the current value and store a new value in the destination. */
#ifdef __GNUCLIKE_ASM
static __inline u_int
-atomic_readandclear_int(volatile u_int *addr)
+atomic_swap_int(volatile u_int *p, u_int v)
{
- u_int res;
- res = 0;
__asm __volatile(
- " xchgl %1,%0 ; "
- "# atomic_readandclear_int"
- : "+r" (res), /* 0 */
- "=m" (*addr) /* 1 */
- : "m" (*addr));
-
- return (res);
+ " xchgl %1, %0 ; "
+ "# atomic_swap_int"
+ : "+r" (v), /* 0 */
+ "=m" (*p) /* 1 */
+ : "m" (*p));
+ return (v);
}
static __inline u_long
-atomic_readandclear_long(volatile u_long *addr)
+atomic_swap_long(volatile u_long *p, u_long v)
{
- u_long res;
- res = 0;
- __asm __volatile(
- " xchgl %1,%0 ; "
- "# atomic_readandclear_long"
- : "+r" (res), /* 0 */
- "=m" (*addr) /* 1 */
- : "m" (*addr));
-
- return (res);
+ return (atomic_swap_int((volatile u_int *)p, (u_int)v));
}
#else /* !__GNUCLIKE_ASM */
-u_int atomic_readandclear_int(volatile u_int *addr);
-u_long atomic_readandclear_long(volatile u_long *addr);
+u_int atomic_swap_int(volatile u_int *, u_int);
+u_long atomic_swap_long(volatile u_long *, u_long);
#endif /* __GNUCLIKE_ASM */
@@ -474,6 +464,9 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_acq_long atomic_cmpset_long
#define atomic_cmpset_rel_long atomic_cmpset_long
+#define atomic_readandclear_int(p) atomic_swap_int(p, 0)
+#define atomic_readandclear_long(p) atomic_swap_long(p, 0)
+
/* Operations on 8-bit bytes. */
#define atomic_set_8 atomic_set_char
#define atomic_set_acq_8 atomic_set_acq_char
@@ -524,6 +517,7 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_32 atomic_cmpset_int
#define atomic_cmpset_acq_32 atomic_cmpset_acq_int
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
+#define atomic_swap_32 atomic_swap_int
#define atomic_readandclear_32 atomic_readandclear_int
#define atomic_fetchadd_32 atomic_fetchadd_int
@@ -564,6 +558,8 @@ u_long atomic_readandclear_long(volatile
#define atomic_cmpset_rel_ptr(dst, old, new) \
atomic_cmpset_rel_int((volatile u_int *)(dst), (u_int)(old), \
(u_int)(new))
+#define atomic_swap_ptr(p, v) \
+ atomic_swap_int((volatile u_int *)(p), (u_int)(v))
#define atomic_readandclear_ptr(p) \
atomic_readandclear_int((volatile u_int *)(p))
More information about the svn-src-projects
mailing list