summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include/atomic.h
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-09-27 17:39:11 +0000
committerjhb <jhb@FreeBSD.org>2005-09-27 17:39:11 +0000
commit89caa56972d968272278a67fe10affb38d9e88eb (patch)
tree368df1c62ea6aa397797927efbf9c7ccc4b3b92e /sys/amd64/include/atomic.h
parentaa790ae8700e7fed7ef83f2549c6bc53d6ae7f8f (diff)
downloadFreeBSD-src-89caa56972d968272278a67fe10affb38d9e88eb.zip
FreeBSD-src-89caa56972d968272278a67fe10affb38d9e88eb.tar.gz
Add a new atomic_fetchadd() primitive that atomically adds a value to a
variable and returns the previous value of the variable. Tested on: i386, alpha, sparc64, arm (cognet) Reviewed by: arch@ Submitted by: cognet (arm) MFC after: 1 week
Diffstat (limited to 'sys/amd64/include/atomic.h')
-rw-r--r--sys/amd64/include/atomic.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index 2d59167..fbdbd8f 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -73,6 +73,7 @@ void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src);
+u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
@@ -154,6 +155,25 @@ atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src)
return (res);
}
+/*
+ * Atomically add the value of v to the integer pointed to by p and return
+ * the previous value of *p.
+ */
+static __inline u_int
+atomic_fetchadd_int(volatile u_int *p, u_int v)
+{
+
+ __asm __volatile (
+ " " __XSTRING(MPLOCKED) " "
+ " xaddl %0, %1 ; "
+ "# atomic_fetchadd_int"
+ : "+r" (v), /* 0 (result) */
+ "=m" (*p) /* 1 */
+ : "m" (*p)); /* 2 */
+
+ return (v);
+}
+
#if defined(_KERNEL) && !defined(SMP)
/*
@@ -375,6 +395,7 @@ u_long atomic_readandclear_long(volatile u_long *);
#define atomic_cmpset_acq_32 atomic_cmpset_acq_int
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
#define atomic_readandclear_32 atomic_readandclear_int
+#define atomic_fetchadd_32 atomic_fetchadd_int
/* Operations on 64-bit quad words. */
#define atomic_set_64 atomic_set_long
OpenPOWER on IntegriCloud