diff options
author | Remy Noel <mocramis@gmail.com> | 2018-05-03 16:15:28 +0200 |
---|---|---|
committer | Remy Noel <mocramis@gmail.com> | 2018-05-03 16:15:28 +0200 |
commit | 58c17bd912ec450f8132597cdba6afd300a63586 (patch) | |
tree | bc78f8d7fc585e4d4762daccf9cbd62f95791ceb /arch/x86/machine | |
parent | bf16bb3d761063aee9ee2b20aba15a7267d473ac (diff) | |
parent | 7769b9765c40a78b8af2568161da404e4e22a77c (diff) |
Merge branch 'master' into perfmon
Diffstat (limited to 'arch/x86/machine')
-rw-r--r-- | arch/x86/machine/atomic.h | 109 | ||||
-rw-r--r-- | arch/x86/machine/trap.c | 2 |
2 files changed, 51 insertions, 60 deletions
diff --git a/arch/x86/machine/atomic.h b/arch/x86/machine/atomic.h index 36f0067..e10d301 100644 --- a/arch/x86/machine/atomic.h +++ b/arch/x86/machine/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 Richard Braun. + * Copyright (c) 2012-2018 Richard Braun. * Copyright (c) 2017 Agustina Arzille. * * This program is free software: you can redistribute it and/or modify @@ -27,78 +27,69 @@ #endif #include <stdbool.h> -#include <stdint.h> +#include <kern/atomic_types.h> #include <kern/macros.h> -#ifndef __LP64__ +#ifdef __LP64__ -/* - * On i386, the compiler 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. Note that, in this case, - * loading becomes a potentially mutating operation, but it's not expected - * to be a problem since atomic operations are normally not used on read-only - * memory. Also note that this assumes the processor is at least an i586. - */ +/* Report that 64-bits operations are supported */ +#define ATOMIC_HAVE_64B_OPS -/* - * Temporarily discard qualifiers when loading 64-bits values with a - * compare-and-swap operation. - */ -#define atomic_load_64(ptr, mo) \ -MACRO_BEGIN \ - uint64_t ret_ = 0; \ - \ - __atomic_compare_exchange_n((uint64_t *)(ptr), &ret_, 0, \ - false, mo, __ATOMIC_RELAXED); \ - ret_; \ -MACRO_END - -#define atomic_load(ptr, mo) \ - (typeof(*(ptr)))__builtin_choose_expr(sizeof(*(ptr)) == 8, \ - atomic_load_64(ptr, mo), \ - __atomic_load_n(ptr, mo)) - -#define atomic_store(ptr, val, mo) \ -MACRO_BEGIN \ - if (sizeof(*(ptr)) != 8) { \ - __atomic_store_n(ptr, val, mo); \ - } else { \ - typeof(*(ptr)) oval_, nval_; \ - bool done_; \ - \ - oval_ = *(ptr); \ - nval_ = (val); \ - \ - do { \ - done_ = __atomic_compare_exchange_n(ptr, &oval_, nval_, \ - false, mo, \ - __ATOMIC_RELAXED); \ - } while (!done_); \ - \ - } \ -MACRO_END +#else /* __LP64__ */ /* - * Report that load and store are architecture-specific. + * XXX Clang doesn't provide any __atomic_xxx_8 functions on i386. */ -#define ATOMIC_ARCH_SPECIFIC_LOAD -#define ATOMIC_ARCH_SPECIFIC_STORE +#ifndef __clang__ -#endif /* __LP64__ */ +/* Report that 64-bits operations are supported */ +#define ATOMIC_HAVE_64B_OPS /* - * XXX Clang seems to have trouble with 64-bits operations on 32-bits - * processors. + * 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. + * + * XXX Note that, in this case, loading becomes a potentially mutating + * operation, but it's not expected to be a problem since atomic operations + * are normally not used on read-only memory. + * + * Also note that this assumes the processor is at least an i586. */ -#if defined(__LP64__) || !defined(__clang__) -/* - * Report that 64-bits operations are supported. - */ -#define ATOMIC_HAVE_64B_OPS +static inline unsigned long long +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.ull_ptr), + &prev, 0, false, memorder, __ATOMIC_RELAXED); + return prev; +} + +#define atomic_load_64 atomic_i386_load_64 + +static inline void +atomic_i386_store_64(union atomic_ptr_64 ptr, union atomic_val_64 val, + int memorder) +{ + unsigned long long prev; + bool done; + + prev = *ptr.ull_ptr; + + do { + done = __atomic_compare_exchange_n(ptr.ull_ptr, &prev, val.ull, + false, memorder, __ATOMIC_RELAXED); + } while (!done); +} + +#define atomic_store_64 atomic_i386_store_64 #endif /* __clang__ */ +#endif /* __LP64__ */ + #endif /* X86_ATOMIC_H */ diff --git a/arch/x86/machine/trap.c b/arch/x86/machine/trap.c index a7a5cbd..aaf49ea 100644 --- a/arch/x86/machine/trap.c +++ b/arch/x86/machine/trap.c @@ -91,7 +91,7 @@ static void __init trap_handler_init(struct trap_handler *handler, int flags, trap_handler_fn_t fn) { handler->flags = flags; - atomic_store(&handler->fn, fn, ATOMIC_RELAXED); + handler->fn = fn; } static void __init |