summaryrefslogtreecommitdiffstats
path: root/sys/alpha
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/alpha
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/alpha')
-rw-r--r--sys/alpha/include/atomic.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/sys/alpha/include/atomic.h b/sys/alpha/include/atomic.h
index 7277600..adae6ec 100644
--- a/sys/alpha/include/atomic.h
+++ b/sys/alpha/include/atomic.h
@@ -365,6 +365,27 @@ atomic_cmpset_rel_64(volatile u_int64_t *p, u_int64_t cmpval, u_int64_t newval)
return (atomic_cmpset_64(p, cmpval, newval));
}
+/*
+ * 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_32(volatile u_int32_t *p, u_int32_t v)
+{
+ u_int32_t value, temp;
+
+#ifdef __GNUCLIKE_ASM
+ __asm __volatile (
+ "1:\tldl_l %0, %1\n\t" /* load old value */
+ "addl %0, %3, %2\n\t" /* calculate new value */
+ "stl_c %2, %1\n\t" /* attempt to store */
+ "beq %2, 1b\n" /* spin if failed */
+ : "=&r" (value), "=m" (*p), "=r" (temp)
+ : "r" (v), "m" (*p));
+#endif
+ return (value);
+}
+
/* Operations on chars. */
#define atomic_set_char atomic_set_8
#define atomic_set_acq_char atomic_set_acq_8
@@ -412,6 +433,7 @@ atomic_cmpset_rel_64(volatile u_int64_t *p, u_int64_t cmpval, u_int64_t newval)
#define atomic_load_acq_int atomic_load_acq_32
#define atomic_store_rel_int atomic_store_rel_32
#define atomic_readandclear_int atomic_readandclear_32
+#define atomic_fetchadd_int atomic_fetchadd_32
/* Operations on longs. */
#define atomic_set_long atomic_set_64
OpenPOWER on IntegriCloud