diff options
author | jhb <jhb@FreeBSD.org> | 2005-07-09 12:38:53 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2005-07-09 12:38:53 +0000 |
commit | febd45c7d3ecb1509db168f47773b5bae9687380 (patch) | |
tree | 29ec7fe99ef28adcdcf6f44b881d13237e99d100 /sys/amd64 | |
parent | d7eebc79f5c29ccf565dbc72e363390e606a3f48 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/amd64/include/atomic.h | 142 |
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_ */ |