diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-04-07 10:53:41 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-05-08 15:11:05 -0400 |
commit | da6d8567512df11e0473b710c07de87efde5709c (patch) | |
tree | 24601b1c6d8347e03517c8c24959171ba34dd3c5 | |
parent | 42b09d7b0e3d57a92b938fde5fcb532e9a88e1ea (diff) |
tools include: Add basic atomic.h implementation from the kernel sources
Uses the arch/x86/ kernel code for x86_64/i386, fallbacking to a gcc
intrinsics implementation that has been tested in at least sparc64.
Will be used for reference counting in tools/perf.
Acked-by: David Ahern <dsahern@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Don Zickus <dzickus@redhat.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-knfpjowhgyh6x4z0kfuk389j@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/arch/x86/include/asm/atomic.h | 65 | ||||
-rw-r--r-- | tools/arch/x86/include/asm/rmwcc.h | 41 | ||||
-rw-r--r-- | tools/include/asm-generic/atomic-gcc.h | 63 | ||||
-rw-r--r-- | tools/include/asm/atomic.h | 10 | ||||
-rw-r--r-- | tools/include/linux/atomic.h | 6 | ||||
-rw-r--r-- | tools/include/linux/types.h | 4 | ||||
-rw-r--r-- | tools/perf/MANIFEST | 4 |
7 files changed, 193 insertions, 0 deletions
diff --git a/tools/arch/x86/include/asm/atomic.h b/tools/arch/x86/include/asm/atomic.h new file mode 100644 index 000000000000..059e33e94260 --- /dev/null +++ b/tools/arch/x86/include/asm/atomic.h | |||
@@ -0,0 +1,65 @@ | |||
1 | #ifndef _TOOLS_LINUX_ASM_X86_ATOMIC_H | ||
2 | #define _TOOLS_LINUX_ASM_X86_ATOMIC_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <linux/types.h> | ||
6 | #include "rmwcc.h" | ||
7 | |||
8 | #define LOCK_PREFIX "\n\tlock; " | ||
9 | |||
10 | /* | ||
11 | * Atomic operations that C can't guarantee us. Useful for | ||
12 | * resource counting etc.. | ||
13 | */ | ||
14 | |||
15 | #define ATOMIC_INIT(i) { (i) } | ||
16 | |||
17 | /** | ||
18 | * atomic_read - read atomic variable | ||
19 | * @v: pointer of type atomic_t | ||
20 | * | ||
21 | * Atomically reads the value of @v. | ||
22 | */ | ||
23 | static inline int atomic_read(const atomic_t *v) | ||
24 | { | ||
25 | return ACCESS_ONCE((v)->counter); | ||
26 | } | ||
27 | |||
28 | /** | ||
29 | * atomic_set - set atomic variable | ||
30 | * @v: pointer of type atomic_t | ||
31 | * @i: required value | ||
32 | * | ||
33 | * Atomically sets the value of @v to @i. | ||
34 | */ | ||
35 | static inline void atomic_set(atomic_t *v, int i) | ||
36 | { | ||
37 | v->counter = i; | ||
38 | } | ||
39 | |||
40 | /** | ||
41 | * atomic_inc - increment atomic variable | ||
42 | * @v: pointer of type atomic_t | ||
43 | * | ||
44 | * Atomically increments @v by 1. | ||
45 | */ | ||
46 | static inline void atomic_inc(atomic_t *v) | ||
47 | { | ||
48 | asm volatile(LOCK_PREFIX "incl %0" | ||
49 | : "+m" (v->counter)); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * atomic_dec_and_test - decrement and test | ||
54 | * @v: pointer of type atomic_t | ||
55 | * | ||
56 | * Atomically decrements @v by 1 and | ||
57 | * returns true if the result is 0, or false for all other | ||
58 | * cases. | ||
59 | */ | ||
60 | static inline int atomic_dec_and_test(atomic_t *v) | ||
61 | { | ||
62 | GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", "e"); | ||
63 | } | ||
64 | |||
65 | #endif /* _TOOLS_LINUX_ASM_X86_ATOMIC_H */ | ||
diff --git a/tools/arch/x86/include/asm/rmwcc.h b/tools/arch/x86/include/asm/rmwcc.h new file mode 100644 index 000000000000..a6669bc06939 --- /dev/null +++ b/tools/arch/x86/include/asm/rmwcc.h | |||
@@ -0,0 +1,41 @@ | |||
1 | #ifndef _TOOLS_LINUX_ASM_X86_RMWcc | ||
2 | #define _TOOLS_LINUX_ASM_X86_RMWcc | ||
3 | |||
4 | #ifdef CC_HAVE_ASM_GOTO | ||
5 | |||
6 | #define __GEN_RMWcc(fullop, var, cc, ...) \ | ||
7 | do { \ | ||
8 | asm_volatile_goto (fullop "; j" cc " %l[cc_label]" \ | ||
9 | : : "m" (var), ## __VA_ARGS__ \ | ||
10 | : "memory" : cc_label); \ | ||
11 | return 0; \ | ||
12 | cc_label: \ | ||
13 | return 1; \ | ||
14 | } while (0) | ||
15 | |||
16 | #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ | ||
17 | __GEN_RMWcc(op " " arg0, var, cc) | ||
18 | |||
19 | #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ | ||
20 | __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) | ||
21 | |||
22 | #else /* !CC_HAVE_ASM_GOTO */ | ||
23 | |||
24 | #define __GEN_RMWcc(fullop, var, cc, ...) \ | ||
25 | do { \ | ||
26 | char c; \ | ||
27 | asm volatile (fullop "; set" cc " %1" \ | ||
28 | : "+m" (var), "=qm" (c) \ | ||
29 | : __VA_ARGS__ : "memory"); \ | ||
30 | return c != 0; \ | ||
31 | } while (0) | ||
32 | |||
33 | #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ | ||
34 | __GEN_RMWcc(op " " arg0, var, cc) | ||
35 | |||
36 | #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ | ||
37 | __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) | ||
38 | |||
39 | #endif /* CC_HAVE_ASM_GOTO */ | ||
40 | |||
41 | #endif /* _TOOLS_LINUX_ASM_X86_RMWcc */ | ||
diff --git a/tools/include/asm-generic/atomic-gcc.h b/tools/include/asm-generic/atomic-gcc.h new file mode 100644 index 000000000000..2ba78c9f5701 --- /dev/null +++ b/tools/include/asm-generic/atomic-gcc.h | |||
@@ -0,0 +1,63 @@ | |||
1 | #ifndef __TOOLS_ASM_GENERIC_ATOMIC_H | ||
2 | #define __TOOLS_ASM_GENERIC_ATOMIC_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <linux/types.h> | ||
6 | |||
7 | /* | ||
8 | * Atomic operations that C can't guarantee us. Useful for | ||
9 | * resource counting etc.. | ||
10 | * | ||
11 | * Excerpts obtained from the Linux kernel sources. | ||
12 | */ | ||
13 | |||
14 | #define ATOMIC_INIT(i) { (i) } | ||
15 | |||
16 | /** | ||
17 | * atomic_read - read atomic variable | ||
18 | * @v: pointer of type atomic_t | ||
19 | * | ||
20 | * Atomically reads the value of @v. | ||
21 | */ | ||
22 | static inline int atomic_read(const atomic_t *v) | ||
23 | { | ||
24 | return ACCESS_ONCE((v)->counter); | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * atomic_set - set atomic variable | ||
29 | * @v: pointer of type atomic_t | ||
30 | * @i: required value | ||
31 | * | ||
32 | * Atomically sets the value of @v to @i. | ||
33 | */ | ||
34 | static inline void atomic_set(atomic_t *v, int i) | ||
35 | { | ||
36 | v->counter = i; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * atomic_inc - increment atomic variable | ||
41 | * @v: pointer of type atomic_t | ||
42 | * | ||
43 | * Atomically increments @v by 1. | ||
44 | */ | ||
45 | static inline void atomic_inc(atomic_t *v) | ||
46 | { | ||
47 | __sync_add_and_fetch(&v->counter, 1); | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * atomic_dec_and_test - decrement and test | ||
52 | * @v: pointer of type atomic_t | ||
53 | * | ||
54 | * Atomically decrements @v by 1 and | ||
55 | * returns true if the result is 0, or false for all other | ||
56 | * cases. | ||
57 | */ | ||
58 | static inline int atomic_dec_and_test(atomic_t *v) | ||
59 | { | ||
60 | return __sync_sub_and_fetch(&v->counter, 1) == 0; | ||
61 | } | ||
62 | |||
63 | #endif /* __TOOLS_ASM_GENERIC_ATOMIC_H */ | ||
diff --git a/tools/include/asm/atomic.h b/tools/include/asm/atomic.h new file mode 100644 index 000000000000..70794f538a86 --- /dev/null +++ b/tools/include/asm/atomic.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef __TOOLS_LINUX_ASM_ATOMIC_H | ||
2 | #define __TOOLS_LINUX_ASM_ATOMIC_H | ||
3 | |||
4 | #if defined(__i386__) || defined(__x86_64__) | ||
5 | #include "../../arch/x86/include/asm/atomic.h" | ||
6 | #else | ||
7 | #include <asm-generic/atomic-gcc.h> | ||
8 | #endif | ||
9 | |||
10 | #endif /* __TOOLS_LINUX_ASM_ATOMIC_H */ | ||
diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h new file mode 100644 index 000000000000..4e3d3d18ebab --- /dev/null +++ b/tools/include/linux/atomic.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __TOOLS_LINUX_ATOMIC_H | ||
2 | #define __TOOLS_LINUX_ATOMIC_H | ||
3 | |||
4 | #include <asm/atomic.h> | ||
5 | |||
6 | #endif /* __TOOLS_LINUX_ATOMIC_H */ | ||
diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h index b5cf25e05df2..0bdeda66aae5 100644 --- a/tools/include/linux/types.h +++ b/tools/include/linux/types.h | |||
@@ -60,6 +60,10 @@ typedef __u32 __bitwise __be32; | |||
60 | typedef __u64 __bitwise __le64; | 60 | typedef __u64 __bitwise __le64; |
61 | typedef __u64 __bitwise __be64; | 61 | typedef __u64 __bitwise __be64; |
62 | 62 | ||
63 | typedef struct { | ||
64 | int counter; | ||
65 | } atomic_t; | ||
66 | |||
63 | struct list_head { | 67 | struct list_head { |
64 | struct list_head *next, *prev; | 68 | struct list_head *next, *prev; |
65 | }; | 69 | }; |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 7ef14d4434a4..a83cf75164e1 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -14,11 +14,14 @@ tools/arch/x86/include/asm/barrier.h | |||
14 | tools/arch/xtensa/include/asm/barrier.h | 14 | tools/arch/xtensa/include/asm/barrier.h |
15 | tools/scripts | 15 | tools/scripts |
16 | tools/build | 16 | tools/build |
17 | tools/arch/x86/include/asm/atomic.h | ||
18 | tools/arch/x86/include/asm/rmwcc.h | ||
17 | tools/lib/traceevent | 19 | tools/lib/traceevent |
18 | tools/lib/api | 20 | tools/lib/api |
19 | tools/lib/symbol/kallsyms.c | 21 | tools/lib/symbol/kallsyms.c |
20 | tools/lib/symbol/kallsyms.h | 22 | tools/lib/symbol/kallsyms.h |
21 | tools/lib/util/find_next_bit.c | 23 | tools/lib/util/find_next_bit.c |
24 | tools/include/asm/atomic.h | ||
22 | tools/include/asm/barrier.h | 25 | tools/include/asm/barrier.h |
23 | tools/include/asm/bug.h | 26 | tools/include/asm/bug.h |
24 | tools/include/asm-generic/barrier.h | 27 | tools/include/asm-generic/barrier.h |
@@ -32,6 +35,7 @@ tools/include/asm-generic/bitops/fls64.h | |||
32 | tools/include/asm-generic/bitops/fls.h | 35 | tools/include/asm-generic/bitops/fls.h |
33 | tools/include/asm-generic/bitops/hweight.h | 36 | tools/include/asm-generic/bitops/hweight.h |
34 | tools/include/asm-generic/bitops.h | 37 | tools/include/asm-generic/bitops.h |
38 | tools/include/linux/atomic.h | ||
35 | tools/include/linux/bitops.h | 39 | tools/include/linux/bitops.h |
36 | tools/include/linux/compiler.h | 40 | tools/include/linux/compiler.h |
37 | tools/include/linux/export.h | 41 | tools/include/linux/export.h |