Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+193
+65
tools/arch/x86/include/asm/atomic.h
··· 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 */
+41
tools/arch/x86/include/asm/rmwcc.h
··· 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 */
+63
tools/include/asm-generic/atomic-gcc.h
··· 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 */
+10
tools/include/asm/atomic.h
··· 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 */
+6
tools/include/linux/atomic.h
··· 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 */
+4
tools/include/linux/types.h
··· 60 60 typedef __u64 __bitwise __le64; 61 61 typedef __u64 __bitwise __be64; 62 62 63 + typedef struct { 64 + int counter; 65 + } atomic_t; 66 + 63 67 struct list_head { 64 68 struct list_head *next, *prev; 65 69 };
+4
tools/perf/MANIFEST
··· 14 14 tools/arch/xtensa/include/asm/barrier.h 15 15 tools/scripts 16 16 tools/build 17 + tools/arch/x86/include/asm/atomic.h 18 + tools/arch/x86/include/asm/rmwcc.h 17 19 tools/lib/traceevent 18 20 tools/lib/api 19 21 tools/lib/symbol/kallsyms.c 20 22 tools/lib/symbol/kallsyms.h 21 23 tools/lib/util/find_next_bit.c 24 + tools/include/asm/atomic.h 22 25 tools/include/asm/barrier.h 23 26 tools/include/asm/bug.h 24 27 tools/include/asm-generic/barrier.h ··· 35 32 tools/include/asm-generic/bitops/fls.h 36 33 tools/include/asm-generic/bitops/hweight.h 37 34 tools/include/asm-generic/bitops.h 35 + tools/include/linux/atomic.h 38 36 tools/include/linux/bitops.h 39 37 tools/include/linux/compiler.h 40 38 tools/include/linux/export.h