diff options
author | Richard Braun <rbraun@sceen.net> | 2018-04-26 22:33:39 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2018-04-26 22:33:39 +0200 |
commit | 5fe92212b38ea506e7d65ced630f77f9c4a9d944 (patch) | |
tree | 61420cbc4d388ebf3fa09f35db8164fbf82273ca /arch/x86/machine | |
parent | c553980bbaf1781e976b9fa17ff8a20502c43af4 (diff) |
kern/atomic: minor rework
Allow architectures to specifically override any of the overloaded functions.
This removes the need from architecture-specific code to implement selection.
Diffstat (limited to 'arch/x86/machine')
-rw-r--r-- | arch/x86/machine/atomic.h | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/arch/x86/machine/atomic.h b/arch/x86/machine/atomic.h index 5da8568..e10d301 100644 --- a/arch/x86/machine/atomic.h +++ b/arch/x86/machine/atomic.h @@ -28,13 +28,18 @@ #include <stdbool.h> +#include <kern/atomic_types.h> #include <kern/macros.h> -#ifndef __LP64__ +#ifdef __LP64__ + +/* Report that 64-bits operations are supported */ +#define ATOMIC_HAVE_64B_OPS + +#else /* __LP64__ */ /* - * XXX Clang seems to have trouble with 64-bit operations on 32-bit - * processors. + * XXX Clang doesn't provide any __atomic_xxx_8 functions on i386. */ #ifndef __clang__ @@ -42,7 +47,7 @@ #define ATOMIC_HAVE_64B_OPS /* - * On i386, the compiler generates either an FP-stack read/write, or an SSE2 + * On i386, GCC generates either an FP-stack read/write, or an SSE2 * store/load to implement these 64-bit atomic operations. Since that's not * feasible in the kernel, fall back to cmpxchg8b. * @@ -53,51 +58,38 @@ * Also note that this assumes the processor is at least an i586. */ -#define atomic_x86_select(ptr, op) \ -_Generic(*(ptr), \ - unsigned int: __atomic_ ## op ## _n, \ - unsigned long long: atomic_i386_ ## op ## _64) - static inline unsigned long long -atomic_i386_load_64(const unsigned long long *ptr, int memorder) +atomic_i386_load_64(union atomic_constptr_64 ptr, int memorder) { unsigned long long prev; prev = 0; - __atomic_compare_exchange_n((unsigned long long *)ptr, &prev, - 0, false, memorder, __ATOMIC_RELAXED); + __atomic_compare_exchange_n((unsigned long long *)(ptr.ull_ptr), + &prev, 0, false, memorder, __ATOMIC_RELAXED); return prev; } -#define atomic_load_n(ptr, memorder) \ -atomic_x86_select(ptr, load)(ptr, memorder) +#define atomic_load_64 atomic_i386_load_64 static inline void -atomic_i386_store_64(unsigned long long *ptr, unsigned long long val, +atomic_i386_store_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder) { unsigned long long prev; bool done; - prev = *ptr; + prev = *ptr.ull_ptr; do { - done = __atomic_compare_exchange_n(ptr, &prev, val, - false, memorder, - __ATOMIC_RELAXED); + done = __atomic_compare_exchange_n(ptr.ull_ptr, &prev, val.ull, + false, memorder, __ATOMIC_RELAXED); } while (!done); } -#define atomic_store_n(ptr, val, memorder) \ -atomic_x86_select(ptr, store)(ptr, val, memorder) +#define atomic_store_64 atomic_i386_store_64 #endif /* __clang__ */ -#else /* __LP64__ */ - -/* Report that 64-bits operations are supported */ -#define ATOMIC_HAVE_64B_OPS - #endif /* __LP64__ */ #endif /* X86_ATOMIC_H */ |