summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include/atomic.h
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-07-09 12:38:53 +0000
committerjhb <jhb@FreeBSD.org>2005-07-09 12:38:53 +0000
commitfebd45c7d3ecb1509db168f47773b5bae9687380 (patch)
tree29ec7fe99ef28adcdcf6f44b881d13237e99d100 /sys/amd64/include/atomic.h
parentd7eebc79f5c29ccf565dbc72e363390e606a3f48 (diff)
downloadFreeBSD-src-febd45c7d3ecb1509db168f47773b5bae9687380.zip
FreeBSD-src-febd45c7d3ecb1509db168f47773b5bae9687380.tar.gz
Some cleanups and tweaks to some of the atomic.h files in preparation for
further changes and fixes in the future: - Use aliases via macros rather than duplicated inlines wherever possible. - Move all the aliases to the bottom of these files and the inline functions to the top. - Add various comments. - On alpha, drop atomic_{load_acq,store_rel}_{8,char,16,short}(). - On i386 and amd64, don't duplicate the extern declarations for functions in the two non-inline cases (KLD_MODULE and compiler doesn't do inlines), instead, consolidate those two cases. - Some whitespace fixes. Approved by: re (scottl)
Diffstat (limited to 'sys/amd64/include/atomic.h')
-rw-r--r--sys/amd64/include/atomic.h142
1 files changed, 63 insertions, 79 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index eaf8068..296143a 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
#ifndef _MACHINE_ATOMIC_H_
-#define _MACHINE_ATOMIC_H_
+#define _MACHINE_ATOMIC_H_
#ifndef _SYS_CDEFS_H_
#error this file needs sys/cdefs.h as a prerequisite
@@ -67,8 +67,8 @@
* Kernel modules call real functions which are built into the kernel.
* This allows kernel modules to be portable between UP and SMP systems.
*/
-#if defined(KLD_MODULE)
-#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
+#if defined(KLD_MODULE) || !(defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE))
+#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
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);
@@ -78,25 +78,23 @@ int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src);
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
-#else /* !KLD_MODULE */
-
-#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
+#else /* !KLD_MODULE && __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
/*
* For userland, assume the SMP case and use lock prefixes so that
* the binaries will run on both types of systems.
*/
#if defined(SMP) || !defined(_KERNEL)
-#define MPLOCKED lock ;
+#define MPLOCKED lock ;
#else
-#define MPLOCKED
+#define MPLOCKED
#endif
/*
* The assembly is volatilized to demark potential before-and-after side
* effects if an interrupt or SMP collision were to occur.
*/
-#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
+#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
static __inline void \
atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
{ \
@@ -106,13 +104,6 @@ atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
} \
struct __hack
-#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
-
-#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
-extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
-
-#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
-
/*
* Atomic compare and set, used by the mutex functions
*
@@ -121,8 +112,6 @@ extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
* Returns 0 on failure, non-zero on success
*/
-#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
-
static __inline int
atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
{
@@ -162,11 +151,8 @@ atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src)
return (res);
}
-#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
-
-#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
-#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
+#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
static __inline u_##TYPE \
atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
{ \
@@ -193,18 +179,7 @@ atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
} \
struct __hack
-#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
-
-extern int atomic_cmpset_int(volatile u_int *, u_int, u_int);
-extern int atomic_cmpset_long(volatile u_long *, u_long, u_long);
-
-#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
-extern u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
-extern void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
-
-#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
-
-#endif /* KLD_MODULE */
+#endif /* KLD_MODULE || !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v);
ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v);
@@ -234,6 +209,49 @@ ATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0");
#undef ATOMIC_ASM
#undef ATOMIC_STORE_LOAD
+#if !defined(WANT_FUNCTIONS)
+
+/* Read the current value and store a zero in the destination. */
+#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
+
+static __inline u_int
+atomic_readandclear_int(volatile u_int *addr)
+{
+ u_int result;
+
+ __asm __volatile (
+ " xorl %0,%0 ; "
+ " xchgl %1,%0 ; "
+ "# atomic_readandclear_int"
+ : "=&r" (result) /* 0 (result) */
+ : "m" (*addr)); /* 1 (addr) */
+
+ return (result);
+}
+
+static __inline u_long
+atomic_readandclear_long(volatile u_long *addr)
+{
+ u_long result;
+
+ __asm __volatile (
+ " xorq %0,%0 ; "
+ " xchgq %1,%0 ; "
+ "# atomic_readandclear_long"
+ : "=&r" (result) /* 0 (result) */
+ : "m" (*addr)); /* 1 (addr) */
+
+ return (result);
+}
+
+#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
+
+u_int atomic_readandclear_int(volatile u_int *);
+u_long atomic_readandclear_long(volatile u_long *);
+
+#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
+
+/* Acquire and release variants are identical to the normal ones. */
#define atomic_set_acq_char atomic_set_char
#define atomic_set_rel_char atomic_set_char
#define atomic_clear_acq_char atomic_clear_char
@@ -260,8 +278,8 @@ ATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0");
#define atomic_add_rel_int atomic_add_int
#define atomic_subtract_acq_int atomic_subtract_int
#define atomic_subtract_rel_int atomic_subtract_int
-#define atomic_cmpset_acq_int atomic_cmpset_int
-#define atomic_cmpset_rel_int atomic_cmpset_int
+#define atomic_cmpset_acq_int atomic_cmpset_int
+#define atomic_cmpset_rel_int atomic_cmpset_int
#define atomic_set_acq_long atomic_set_long
#define atomic_set_rel_long atomic_set_long
@@ -271,10 +289,13 @@ ATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0");
#define atomic_add_rel_long atomic_add_long
#define atomic_subtract_acq_long atomic_subtract_long
#define atomic_subtract_rel_long atomic_subtract_long
+#define atomic_cmpset_acq_long atomic_cmpset_long
+#define atomic_cmpset_rel_long atomic_cmpset_long
-#define atomic_cmpset_acq_ptr atomic_cmpset_ptr
-#define atomic_cmpset_rel_ptr atomic_cmpset_ptr
+#define atomic_cmpset_acq_ptr atomic_cmpset_ptr
+#define atomic_cmpset_rel_ptr atomic_cmpset_ptr
+/* Operations on 8-bit bytes. */
#define atomic_set_8 atomic_set_char
#define atomic_set_acq_8 atomic_set_acq_char
#define atomic_set_rel_8 atomic_set_rel_char
@@ -290,6 +311,7 @@ ATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0");
#define atomic_load_acq_8 atomic_load_acq_char
#define atomic_store_rel_8 atomic_store_rel_char
+/* Operations on 16-bit words. */
#define atomic_set_16 atomic_set_short
#define atomic_set_acq_16 atomic_set_acq_short
#define atomic_set_rel_16 atomic_set_rel_short
@@ -305,6 +327,7 @@ ATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0");
#define atomic_load_acq_16 atomic_load_acq_short
#define atomic_store_rel_16 atomic_store_rel_short
+/* Operations on 32-bit double words. */
#define atomic_set_32 atomic_set_int
#define atomic_set_acq_32 atomic_set_acq_int
#define atomic_set_rel_32 atomic_set_rel_int
@@ -324,7 +347,7 @@ ATOMIC_STORE_LOAD(long, "cmpxchgq %0,%1", "xchgq %1,%0");
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
#define atomic_readandclear_32 atomic_readandclear_int
-#if !defined(WANT_FUNCTIONS)
+/* Operations on pointers. */
static __inline int
atomic_cmpset_ptr(volatile void *dst, void *exp, void *src)
{
@@ -349,7 +372,7 @@ atomic_store_rel_ptr(volatile void *p, void *v)
atomic_store_rel_long((volatile u_long *)p, (u_long)v);
}
-#define ATOMIC_PTR(NAME) \
+#define ATOMIC_PTR(NAME) \
static __inline void \
atomic_##NAME##_ptr(volatile void *p, uintptr_t v) \
{ \
@@ -375,44 +398,5 @@ ATOMIC_PTR(subtract)
#undef ATOMIC_PTR
-#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
-
-static __inline u_int
-atomic_readandclear_int(volatile u_int *addr)
-{
- u_int result;
-
- __asm __volatile (
- " xorl %0,%0 ; "
- " xchgl %1,%0 ; "
- "# atomic_readandclear_int"
- : "=&r" (result) /* 0 (result) */
- : "m" (*addr)); /* 1 (addr) */
-
- return (result);
-}
-
-static __inline u_long
-atomic_readandclear_long(volatile u_long *addr)
-{
- u_long result;
-
- __asm __volatile (
- " xorq %0,%0 ; "
- " xchgq %1,%0 ; "
- "# atomic_readandclear_int"
- : "=&r" (result) /* 0 (result) */
- : "m" (*addr)); /* 1 (addr) */
-
- return (result);
-}
-
-#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
-
-extern u_long atomic_readandclear_long(volatile u_long *);
-extern u_int atomic_readandclear_int(volatile u_int *);
-
-#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
-
#endif /* !defined(WANT_FUNCTIONS) */
#endif /* ! _MACHINE_ATOMIC_H_ */
OpenPOWER on IntegriCloud