diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-07-05 13:12:42 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-07-05 14:05:00 -0400 |
| commit | 728abda6a6654ee7f4e903dc921c6307065e1644 (patch) | |
| tree | a4cba7310c2cfae2039229c354e5dff77216286d /tools/include/linux | |
| parent | b9df84fd7c05cc300d6d14f022b8a00773ebcf8c (diff) | |
tools: Adopt {READ,WRITE_ONCE} from the kernel
We need it to build rbtree.c after this cset:
commit d72da4a4d973
Author: Peter Zijlstra <peterz@infradead.org>
Date: Wed May 27 11:09:36 2015 +0930
rbtree: Make lockless searches non-fatal
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-qlnzhezv5ddwst0w9fydju0y@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/include/linux')
| -rw-r--r-- | tools/include/linux/compiler.h | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index f0e72674c52d..9098083869c8 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h | |||
| @@ -41,4 +41,62 @@ | |||
| 41 | 41 | ||
| 42 | #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) | 42 | #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) |
| 43 | 43 | ||
| 44 | #include <linux/types.h> | ||
| 45 | |||
| 46 | static __always_inline void __read_once_size(const volatile void *p, void *res, int size) | ||
| 47 | { | ||
| 48 | switch (size) { | ||
| 49 | case 1: *(__u8 *)res = *(volatile __u8 *)p; break; | ||
| 50 | case 2: *(__u16 *)res = *(volatile __u16 *)p; break; | ||
| 51 | case 4: *(__u32 *)res = *(volatile __u32 *)p; break; | ||
| 52 | case 8: *(__u64 *)res = *(volatile __u64 *)p; break; | ||
| 53 | default: | ||
| 54 | barrier(); | ||
| 55 | __builtin_memcpy((void *)res, (const void *)p, size); | ||
| 56 | barrier(); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | static __always_inline void __write_once_size(volatile void *p, void *res, int size) | ||
| 61 | { | ||
| 62 | switch (size) { | ||
| 63 | case 1: *(volatile __u8 *)p = *(__u8 *)res; break; | ||
| 64 | case 2: *(volatile __u16 *)p = *(__u16 *)res; break; | ||
| 65 | case 4: *(volatile __u32 *)p = *(__u32 *)res; break; | ||
| 66 | case 8: *(volatile __u64 *)p = *(__u64 *)res; break; | ||
| 67 | default: | ||
| 68 | barrier(); | ||
| 69 | __builtin_memcpy((void *)p, (const void *)res, size); | ||
| 70 | barrier(); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Prevent the compiler from merging or refetching reads or writes. The | ||
| 76 | * compiler is also forbidden from reordering successive instances of | ||
| 77 | * READ_ONCE, WRITE_ONCE and ACCESS_ONCE (see below), but only when the | ||
| 78 | * compiler is aware of some particular ordering. One way to make the | ||
| 79 | * compiler aware of ordering is to put the two invocations of READ_ONCE, | ||
| 80 | * WRITE_ONCE or ACCESS_ONCE() in different C statements. | ||
| 81 | * | ||
| 82 | * In contrast to ACCESS_ONCE these two macros will also work on aggregate | ||
| 83 | * data types like structs or unions. If the size of the accessed data | ||
| 84 | * type exceeds the word size of the machine (e.g., 32 bits or 64 bits) | ||
| 85 | * READ_ONCE() and WRITE_ONCE() will fall back to memcpy and print a | ||
| 86 | * compile-time warning. | ||
| 87 | * | ||
| 88 | * Their two major use cases are: (1) Mediating communication between | ||
| 89 | * process-level code and irq/NMI handlers, all running on the same CPU, | ||
| 90 | * and (2) Ensuring that the compiler does not fold, spindle, or otherwise | ||
| 91 | * mutilate accesses that either do not require ordering or that interact | ||
| 92 | * with an explicit memory barrier or atomic instruction that provides the | ||
| 93 | * required ordering. | ||
| 94 | */ | ||
| 95 | |||
| 96 | #define READ_ONCE(x) \ | ||
| 97 | ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) | ||
| 98 | |||
| 99 | #define WRITE_ONCE(x, val) \ | ||
| 100 | ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) | ||
| 101 | |||
| 44 | #endif /* _TOOLS_LINUX_COMPILER_H */ | 102 | #endif /* _TOOLS_LINUX_COMPILER_H */ |
