diff options
author | pjd <pjd@FreeBSD.org> | 2008-03-16 21:20:50 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2008-03-16 21:20:50 +0000 |
commit | ea49d310bf69a1de4effcf20fc368f40b3541ef0 (patch) | |
tree | ef1e5ab50a7584e0e028a94391bd41725fc82f82 | |
parent | bc8c8477a02fa7911713785305f7fe01ee91f393 (diff) | |
download | FreeBSD-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)
-rw-r--r-- | share/man/man9/atomic.9 | 3 | ||||
-rw-r--r-- | sys/amd64/include/atomic.h | 20 | ||||
-rw-r--r-- | sys/i386/include/atomic.h | 7 | ||||
-rw-r--r-- | sys/ia64/include/atomic.h | 11 | ||||
-rw-r--r-- | sys/powerpc/include/atomic.h | 2 | ||||
-rw-r--r-- | sys/sparc64/include/atomic.h | 2 | ||||
-rw-r--r-- | sys/sun4v/include/atomic.h | 2 |
7 files changed, 46 insertions, 1 deletions
diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9 index be5c74ea2..70ee2ab 100644 --- a/share/man/man9/atomic.9 +++ b/share/man/man9/atomic.9 @@ -211,7 +211,8 @@ return tmp; The .Fn atomic_fetchadd functions are only implemented for the types -.Dq Li int +.Dq Li int , +.Dq Li long and .Dq Li 32 and do not have any variants with memory barriers at this time. 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 |