summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2008-03-16 21:20:50 +0000
committerpjd <pjd@FreeBSD.org>2008-03-16 21:20:50 +0000
commitea49d310bf69a1de4effcf20fc368f40b3541ef0 (patch)
treeef1e5ab50a7584e0e028a94391bd41725fc82f82 /sys
parentbc8c8477a02fa7911713785305f7fe01ee91f393 (diff)
downloadFreeBSD-src-ea49d310bf69a1de4effcf20fc368f40b3541ef0.zip
FreeBSD-src-ea49d310bf69a1de4effcf20fc368f40b3541ef0.tar.gz
Implement atomic_fetchadd_long() for all architectures and document it.
Reviewed by: attilio, jhb, jeff, kris (as a part of the uidinfo_waitfree.patch)
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/include/atomic.h20
-rw-r--r--sys/i386/include/atomic.h7
-rw-r--r--sys/ia64/include/atomic.h11
-rw-r--r--sys/powerpc/include/atomic.h2
-rw-r--r--sys/sparc64/include/atomic.h2
-rw-r--r--sys/sun4v/include/atomic.h2
6 files changed, 44 insertions, 0 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index dc12d4d..0edbfff 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -74,6 +74,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);
+u_long atomic_fetchadd_long(volatile u_long *p, u_long v);
#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
@@ -174,6 +175,25 @@ atomic_fetchadd_int(volatile u_int *p, u_int v)
return (v);
}
+/*
+ * Atomically add the value of v to the long integer pointed to by p and return
+ * the previous value of *p.
+ */
+static __inline u_long
+atomic_fetchadd_long(volatile u_long *p, u_long v)
+{
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " xaddq %0, %1 ; "
+ "# atomic_fetchadd_long"
+ : "+r" (v), /* 0 (result) */
+ "=m" (*p) /* 1 */
+ : "m" (*p)); /* 2 */
+
+ return (v);
+}
+
#if defined(_KERNEL) && !defined(SMP)
/*
diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h
index d7465f9a..3662a0f 100644
--- a/sys/i386/include/atomic.h
+++ b/sys/i386/include/atomic.h
@@ -278,6 +278,13 @@ atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src)
(u_int)src));
}
+static __inline u_long
+atomic_fetchadd_long(volatile u_long *p, u_long v)
+{
+
+ return (atomic_fetchadd_int((volatile u_int *)p, (u_int)v));
+}
+
/* Read the current value and store a zero in the destination. */
#ifdef __GNUCLIKE_ASM
diff --git a/sys/ia64/include/atomic.h b/sys/ia64/include/atomic.h
index 985f48f..fd90fa2 100644
--- a/sys/ia64/include/atomic.h
+++ b/sys/ia64/include/atomic.h
@@ -371,4 +371,15 @@ atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
#define atomic_fetchadd_int atomic_fetchadd_32
+static __inline u_long
+atomic_fetchadd_long(volatile u_long *p, u_long v)
+{
+ u_long value;
+
+ do {
+ value = *p;
+ } while (!atomic_cmpset_64(p, value, value + v));
+ return (value);
+}
+
#endif /* ! _MACHINE_ATOMIC_H_ */
diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h
index 12c4935..0d1e3c1 100644
--- a/sys/powerpc/include/atomic.h
+++ b/sys/powerpc/include/atomic.h
@@ -502,5 +502,7 @@ atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
}
#define atomic_fetchadd_int atomic_fetchadd_32
+#define atomic_fetchadd_long(p, v) \
+ (u_long)atomic_fetchadd_32((volatile u_int *)(p), (u_int)(v))
#endif /* ! _MACHINE_ATOMIC_H_ */
diff --git a/sys/sparc64/include/atomic.h b/sys/sparc64/include/atomic.h
index 77d455b..61b7ade 100644
--- a/sys/sparc64/include/atomic.h
+++ b/sys/sparc64/include/atomic.h
@@ -279,6 +279,8 @@ ATOMIC_GEN(ptr, uintptr_t *, uintptr_t, uintptr_t, 64);
#define atomic_fetchadd_int atomic_add_int
#define atomic_fetchadd_32 atomic_add_32
+#define atomic_fetchadd_long(p, v) \
+ (u_long)atomic_add_int((volatile u_int *)(p), (u_int)(v))
#undef ATOMIC_GEN
#undef atomic_cas
diff --git a/sys/sun4v/include/atomic.h b/sys/sun4v/include/atomic.h
index 77d455b..61b7ade 100644
--- a/sys/sun4v/include/atomic.h
+++ b/sys/sun4v/include/atomic.h
@@ -279,6 +279,8 @@ ATOMIC_GEN(ptr, uintptr_t *, uintptr_t, uintptr_t, 64);
#define atomic_fetchadd_int atomic_add_int
#define atomic_fetchadd_32 atomic_add_32
+#define atomic_fetchadd_long(p, v) \
+ (u_long)atomic_add_int((volatile u_int *)(p), (u_int)(v))
#undef ATOMIC_GEN
#undef atomic_cas
OpenPOWER on IntegriCloud