summaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Makefile325
-rw-r--r--tools/perf/bench/mem-memcpy.c1
-rw-r--r--tools/perf/builtin-annotate.c1
-rw-r--r--tools/perf/builtin-kmem.c9
-rw-r--r--tools/perf/builtin-record.c4
-rw-r--r--tools/perf/builtin-report.c23
-rw-r--r--tools/perf/builtin-timechart.c1
-rw-r--r--tools/perf/perf.c1
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN6
-rw-r--r--tools/perf/util/color.c53
-rw-r--r--tools/perf/util/color.h4
-rw-r--r--tools/perf/util/debug.h16
-rw-r--r--tools/perf/util/event.c9
-rw-r--r--tools/perf/util/hist.c66
-rw-r--r--tools/perf/util/hist.h9
-rw-r--r--tools/perf/util/map.c196
-rw-r--r--tools/perf/util/map.h34
-rw-r--r--tools/perf/util/newt.c298
-rw-r--r--tools/perf/util/session.c22
-rw-r--r--tools/perf/util/session.h19
-rw-r--r--tools/perf/util/sort.c93
-rw-r--r--tools/perf/util/sort.h6
-rw-r--r--tools/perf/util/string.h16
-rw-r--r--tools/perf/util/thread.c169
-rw-r--r--tools/perf/util/util.h12
25 files changed, 806 insertions, 587 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 6903645..9f5a47e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -1,3 +1,7 @@
+ifeq ("$(origin O)", "command line")
+ OUTPUT := $(O)/
+endif
+
# The default target of this Makefile is...
all::
@@ -153,9 +157,13 @@ all::
#
# Define NO_DWARF if you do not want debug-info analysis feature at all.
-PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
- @$(SHELL_PATH) util/PERF-VERSION-GEN
--include PERF-VERSION-FILE
+$(shell sh -c 'mkdir -p $(OUTPUT)scripts/python/Perf-Trace-Util/' 2> /dev/null)
+$(shell sh -c 'mkdir -p $(OUTPUT)util/scripting-engines/' 2> /dev/null)
+$(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null)
+
+$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
+ @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
+-include $(OUTPUT)PERF-VERSION-FILE
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
@@ -310,7 +318,7 @@ PROGRAMS += $(EXTRA_PROGRAMS)
#
# Single 'perf' binary right now:
#
-PROGRAMS += perf
+PROGRAMS += $(OUTPUT)perf
# List built-in command $C whose implementation cmd_$C() is not in
# builtin-$C.o but is linked in as part of some other command.
@@ -320,7 +328,7 @@ PROGRAMS += perf
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
# what 'all' will build but not install in perfexecdir
-OTHER_PROGRAMS = perf$X
+OTHER_PROGRAMS = $(OUTPUT)perf$X
# Set paths to tools early so that they can be used for version tests.
ifndef SHELL_PATH
@@ -332,7 +340,7 @@ endif
export PERL_PATH
-LIB_FILE=libperf.a
+LIB_FILE=$(OUTPUT)libperf.a
LIB_H += ../../include/linux/perf_event.h
LIB_H += ../../include/linux/rbtree.h
@@ -377,7 +385,6 @@ LIB_H += util/header.h
LIB_H += util/help.h
LIB_H += util/session.h
LIB_H += util/strbuf.h
-LIB_H += util/string.h
LIB_H += util/strlist.h
LIB_H += util/svghelper.h
LIB_H += util/run-command.h
@@ -393,77 +400,77 @@ LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h
LIB_H += util/cpumap.h
-LIB_OBJS += util/abspath.o
-LIB_OBJS += util/alias.o
-LIB_OBJS += util/build-id.o
-LIB_OBJS += util/config.o
-LIB_OBJS += util/ctype.o
-LIB_OBJS += util/debugfs.o
-LIB_OBJS += util/environment.o
-LIB_OBJS += util/event.o
-LIB_OBJS += util/exec_cmd.o
-LIB_OBJS += util/help.o
-LIB_OBJS += util/levenshtein.o
-LIB_OBJS += util/parse-options.o
-LIB_OBJS += util/parse-events.o
-LIB_OBJS += util/path.o
-LIB_OBJS += util/rbtree.o
-LIB_OBJS += util/bitmap.o
-LIB_OBJS += util/hweight.o
-LIB_OBJS += util/find_next_bit.o
-LIB_OBJS += util/run-command.o
-LIB_OBJS += util/quote.o
-LIB_OBJS += util/strbuf.o
-LIB_OBJS += util/string.o
-LIB_OBJS += util/strlist.o
-LIB_OBJS += util/usage.o
-LIB_OBJS += util/wrapper.o
-LIB_OBJS += util/sigchain.o
-LIB_OBJS += util/symbol.o
-LIB_OBJS += util/color.o
-LIB_OBJS += util/pager.o
-LIB_OBJS += util/header.o
-LIB_OBJS += util/callchain.o
-LIB_OBJS += util/values.o
-LIB_OBJS += util/debug.o
-LIB_OBJS += util/map.o
-LIB_OBJS += util/session.o
-LIB_OBJS += util/thread.o
-LIB_OBJS += util/trace-event-parse.o
-LIB_OBJS += util/trace-event-read.o
-LIB_OBJS += util/trace-event-info.o
-LIB_OBJS += util/trace-event-scripting.o
-LIB_OBJS += util/svghelper.o
-LIB_OBJS += util/sort.o
-LIB_OBJS += util/hist.o
-LIB_OBJS += util/probe-event.o
-LIB_OBJS += util/util.o
-LIB_OBJS += util/cpumap.o
-
-BUILTIN_OBJS += builtin-annotate.o
-
-BUILTIN_OBJS += builtin-bench.o
+LIB_OBJS += $(OUTPUT)util/abspath.o
+LIB_OBJS += $(OUTPUT)util/alias.o
+LIB_OBJS += $(OUTPUT)util/build-id.o
+LIB_OBJS += $(OUTPUT)util/config.o
+LIB_OBJS += $(OUTPUT)util/ctype.o
+LIB_OBJS += $(OUTPUT)util/debugfs.o
+LIB_OBJS += $(OUTPUT)util/environment.o
+LIB_OBJS += $(OUTPUT)util/event.o
+LIB_OBJS += $(OUTPUT)util/exec_cmd.o
+LIB_OBJS += $(OUTPUT)util/help.o
+LIB_OBJS += $(OUTPUT)util/levenshtein.o
+LIB_OBJS += $(OUTPUT)util/parse-options.o
+LIB_OBJS += $(OUTPUT)util/parse-events.o
+LIB_OBJS += $(OUTPUT)util/path.o
+LIB_OBJS += $(OUTPUT)util/rbtree.o
+LIB_OBJS += $(OUTPUT)util/bitmap.o
+LIB_OBJS += $(OUTPUT)util/hweight.o
+LIB_OBJS += $(OUTPUT)util/find_next_bit.o
+LIB_OBJS += $(OUTPUT)util/run-command.o
+LIB_OBJS += $(OUTPUT)util/quote.o
+LIB_OBJS += $(OUTPUT)util/strbuf.o
+LIB_OBJS += $(OUTPUT)util/string.o
+LIB_OBJS += $(OUTPUT)util/strlist.o
+LIB_OBJS += $(OUTPUT)util/usage.o
+LIB_OBJS += $(OUTPUT)util/wrapper.o
+LIB_OBJS += $(OUTPUT)util/sigchain.o
+LIB_OBJS += $(OUTPUT)util/symbol.o
+LIB_OBJS += $(OUTPUT)util/color.o
+LIB_OBJS += $(OUTPUT)util/pager.o
+LIB_OBJS += $(OUTPUT)util/header.o
+LIB_OBJS += $(OUTPUT)util/callchain.o
+LIB_OBJS += $(OUTPUT)util/values.o
+LIB_OBJS += $(OUTPUT)util/debug.o
+LIB_OBJS += $(OUTPUT)util/map.o
+LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/thread.o
+LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
+LIB_OBJS += $(OUTPUT)util/trace-event-read.o
+LIB_OBJS += $(OUTPUT)util/trace-event-info.o
+LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
+LIB_OBJS += $(OUTPUT)util/svghelper.o
+LIB_OBJS += $(OUTPUT)util/sort.o
+LIB_OBJS += $(OUTPUT)util/hist.o
+LIB_OBJS += $(OUTPUT)util/probe-event.o
+LIB_OBJS += $(OUTPUT)util/util.o
+LIB_OBJS += $(OUTPUT)util/cpumap.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
# Benchmark modules
-BUILTIN_OBJS += bench/sched-messaging.o
-BUILTIN_OBJS += bench/sched-pipe.o
-BUILTIN_OBJS += bench/mem-memcpy.o
-
-BUILTIN_OBJS += builtin-diff.o
-BUILTIN_OBJS += builtin-help.o
-BUILTIN_OBJS += builtin-sched.o
-BUILTIN_OBJS += builtin-buildid-list.o
-BUILTIN_OBJS += builtin-buildid-cache.o
-BUILTIN_OBJS += builtin-list.o
-BUILTIN_OBJS += builtin-record.o
-BUILTIN_OBJS += builtin-report.o
-BUILTIN_OBJS += builtin-stat.o
-BUILTIN_OBJS += builtin-timechart.o
-BUILTIN_OBJS += builtin-top.o
-BUILTIN_OBJS += builtin-trace.o
-BUILTIN_OBJS += builtin-probe.o
-BUILTIN_OBJS += builtin-kmem.o
-BUILTIN_OBJS += builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
+BUILTIN_OBJS += $(OUTPUT)builtin-help.o
+BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
+BUILTIN_OBJS += $(OUTPUT)builtin-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-record.o
+BUILTIN_OBJS += $(OUTPUT)builtin-report.o
+BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
+BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
+BUILTIN_OBJS += $(OUTPUT)builtin-top.o
+BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
+BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
PERFLIBS = $(LIB_FILE)
@@ -494,6 +501,10 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
endif
+ifneq ($(OUTPUT),)
+ BASIC_CFLAGS += -I$(OUTPUT)
+endif
+
ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
@@ -512,7 +523,7 @@ else
ifndef NO_DWARF
BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
EXTLIBS += -lelf -ldw
- LIB_OBJS += util/probe-finder.o
+ LIB_OBJS += $(OUTPUT)util/probe-finder.o
endif
endif
@@ -521,7 +532,7 @@ ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtIni
BASIC_CFLAGS += -DNO_NEWT_SUPPORT
else
EXTLIBS += -lnewt
- LIB_OBJS += util/newt.o
+ LIB_OBJS += $(OUTPUT)util/newt.o
endif
ifndef NO_LIBPERL
@@ -533,8 +544,8 @@ ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; e
BASIC_CFLAGS += -DNO_LIBPERL
else
ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
- LIB_OBJS += util/scripting-engines/trace-event-perl.o
- LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
+ LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+ LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
endif
ifndef NO_LIBPYTHON
@@ -542,12 +553,12 @@ PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
endif
-ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o /dev/null $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
+ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o $(BITBUCKET) $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
BASIC_CFLAGS += -DNO_LIBPYTHON
else
ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
- LIB_OBJS += util/scripting-engines/trace-event-python.o
- LIB_OBJS += scripts/python/Perf-Trace-Util/Context.o
+ LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+ LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
endif
ifdef NO_DEMANGLE
@@ -618,53 +629,53 @@ ifdef NO_C99_FORMAT
endif
ifdef SNPRINTF_RETURNS_BOGUS
COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
- COMPAT_OBJS += compat/snprintf.o
+ COMPAT_OBJS += $(OUTPUT)compat/snprintf.o
endif
ifdef FREAD_READS_DIRECTORIES
COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
- COMPAT_OBJS += compat/fopen.o
+ COMPAT_OBJS += $(OUTPUT)compat/fopen.o
endif
ifdef NO_SYMLINK_HEAD
BASIC_CFLAGS += -DNO_SYMLINK_HEAD
endif
ifdef NO_STRCASESTR
COMPAT_CFLAGS += -DNO_STRCASESTR
- COMPAT_OBJS += compat/strcasestr.o
+ COMPAT_OBJS += $(OUTPUT)compat/strcasestr.o
endif
ifdef NO_STRTOUMAX
COMPAT_CFLAGS += -DNO_STRTOUMAX
- COMPAT_OBJS += compat/strtoumax.o
+ COMPAT_OBJS += $(OUTPUT)compat/strtoumax.o
endif
ifdef NO_STRTOULL
COMPAT_CFLAGS += -DNO_STRTOULL
endif
ifdef NO_SETENV
COMPAT_CFLAGS += -DNO_SETENV
- COMPAT_OBJS += compat/setenv.o
+ COMPAT_OBJS += $(OUTPUT)compat/setenv.o
endif
ifdef NO_MKDTEMP
COMPAT_CFLAGS += -DNO_MKDTEMP
- COMPAT_OBJS += compat/mkdtemp.o
+ COMPAT_OBJS += $(OUTPUT)compat/mkdtemp.o
endif
ifdef NO_UNSETENV
COMPAT_CFLAGS += -DNO_UNSETENV
- COMPAT_OBJS += compat/unsetenv.o
+ COMPAT_OBJS += $(OUTPUT)compat/unsetenv.o
endif
ifdef NO_SYS_SELECT_H
BASIC_CFLAGS += -DNO_SYS_SELECT_H
endif
ifdef NO_MMAP
COMPAT_CFLAGS += -DNO_MMAP
- COMPAT_OBJS += compat/mmap.o
+ COMPAT_OBJS += $(OUTPUT)compat/mmap.o
else
ifdef USE_WIN32_MMAP
COMPAT_CFLAGS += -DUSE_WIN32_MMAP
- COMPAT_OBJS += compat/win32mmap.o
+ COMPAT_OBJS += $(OUTPUT)compat/win32mmap.o
endif
endif
ifdef NO_PREAD
COMPAT_CFLAGS += -DNO_PREAD
- COMPAT_OBJS += compat/pread.o
+ COMPAT_OBJS += $(OUTPUT)compat/pread.o
endif
ifdef NO_FAST_WORKING_DIRECTORY
BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
@@ -686,10 +697,10 @@ else
endif
endif
ifdef NO_INET_NTOP
- LIB_OBJS += compat/inet_ntop.o
+ LIB_OBJS += $(OUTPUT)compat/inet_ntop.o
endif
ifdef NO_INET_PTON
- LIB_OBJS += compat/inet_pton.o
+ LIB_OBJS += $(OUTPUT)compat/inet_pton.o
endif
ifdef NO_ICONV
@@ -706,15 +717,15 @@ endif
ifdef PPC_SHA1
SHA1_HEADER = "ppc/sha1.h"
- LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
+ LIB_OBJS += $(OUTPUT)ppc/sha1.o ppc/sha1ppc.o
else
ifdef ARM_SHA1
SHA1_HEADER = "arm/sha1.h"
- LIB_OBJS += arm/sha1.o arm/sha1_arm.o
+ LIB_OBJS += $(OUTPUT)arm/sha1.o $(OUTPUT)arm/sha1_arm.o
else
ifdef MOZILLA_SHA1
SHA1_HEADER = "mozilla-sha1/sha1.h"
- LIB_OBJS += mozilla-sha1/sha1.o
+ LIB_OBJS += $(OUTPUT)mozilla-sha1/sha1.o
else
SHA1_HEADER = <openssl/sha.h>
EXTLIBS += $(LIB_4_CRYPTO)
@@ -726,15 +737,15 @@ ifdef NO_PERL_MAKEMAKER
endif
ifdef NO_HSTRERROR
COMPAT_CFLAGS += -DNO_HSTRERROR
- COMPAT_OBJS += compat/hstrerror.o
+ COMPAT_OBJS += $(OUTPUT)compat/hstrerror.o
endif
ifdef NO_MEMMEM
COMPAT_CFLAGS += -DNO_MEMMEM
- COMPAT_OBJS += compat/memmem.o
+ COMPAT_OBJS += $(OUTPUT)compat/memmem.o
endif
ifdef INTERNAL_QSORT
COMPAT_CFLAGS += -DINTERNAL_QSORT
- COMPAT_OBJS += compat/qsort.o
+ COMPAT_OBJS += $(OUTPUT)compat/qsort.o
endif
ifdef RUNTIME_PREFIX
COMPAT_CFLAGS += -DRUNTIME_PREFIX
@@ -814,7 +825,7 @@ export TAR INSTALL DESTDIR SHELL_PATH
SHELL = $(SHELL_PATH)
-all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS
+all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS
ifneq (,$X)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
endif
@@ -826,39 +837,39 @@ please_set_SHELL_PATH_to_a_more_modern_shell:
shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
-strip: $(PROGRAMS) perf$X
- $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X
+strip: $(PROGRAMS) $(OUTPUT)perf$X
+ $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf$X
-perf.o: perf.c common-cmds.h PERF-CFLAGS
+$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
- $(ALL_CFLAGS) -c $(filter %.c,$^)
+ $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
-perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS)
- $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \
+$(OUTPUT)perf$X: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(OUTPUT)perf.o \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
-builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
'-DPERF_MAN_PATH="$(mandir_SQ)"' \
'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
-builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
'-DPERF_MAN_PATH="$(mandir_SQ)"' \
'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
-$(BUILT_INS): perf$X
+$(BUILT_INS): $(OUTPUT)perf$X
$(QUIET_BUILT_IN)$(RM) $@ && \
ln perf$X $@ 2>/dev/null || \
ln -s perf$X $@ 2>/dev/null || \
cp perf$X $@
-common-cmds.h: util/generate-cmdlist.sh command-list.txt
+$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
-common-cmds.h: $(wildcard Documentation/perf-*.txt)
+$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
$(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
@@ -870,7 +881,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \
$@.sh >$@+ && \
chmod +x $@+ && \
- mv $@+ $@
+ mv $@+ $(OUTPUT)$@
configure: configure.ac
$(QUIET_GEN)$(RM) $@ $<+ && \
@@ -880,60 +891,60 @@ configure: configure.ac
$(RM) $<+
# These can record PERF_VERSION
-perf.o perf.spec \
+$(OUTPUT)perf.o perf.spec \
$(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
- : PERF-VERSION-FILE
+ : $(OUTPUT)PERF-VERSION-FILE
-%.o: %.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
-%.s: %.c PERF-CFLAGS
+$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
+$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
-%.o: %.S
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
+$(OUTPUT)%.o: %.S
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
-util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
'-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
'-DBINDIR="$(bindir_relative_SQ)"' \
'-DPREFIX="$(prefix_SQ)"' \
$<
-builtin-init-db.o: builtin-init-db.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
+$(OUTPUT)builtin-init-db.o: builtin-init-db.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
-util/config.o: util/config.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
# some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing
# from <string.h> that comes from kernel headers wrapping.
KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//`
-util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/bitmap.o: ../../lib/bitmap.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-util/hweight.o: ../../lib/hweight.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o util/hweight.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/hweight.o: ../../lib/hweight.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/find_next_bit.o: ../../lib/find_next_bit.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
-scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o scripts/perl/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
-util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-python.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
-scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c PERF-CFLAGS
- $(QUIET_CC)$(CC) -o scripts/python/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
-perf-%$X: %.o $(PERFLIBS)
+$(OUTPUT)perf-%$X: %.o $(PERFLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
@@ -974,17 +985,17 @@ cscope:
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
-PERF-CFLAGS: .FORCE-PERF-CFLAGS
+$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
@FLAGS='$(TRACK_CFLAGS)'; \
- if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \
+ if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
echo 1>&2 " * new build flags or prefix"; \
- echo "$$FLAGS" >PERF-CFLAGS; \
+ echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
fi
# We need to apply sq twice, once to protect from the shell
-# that runs PERF-BUILD-OPTIONS, and then again to protect it
+# that runs $(OUTPUT)PERF-BUILD-OPTIONS, and then again to protect it
# and the first level quoting from the shell that runs "echo".
-PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
+$(OUTPUT)PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
@echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
@@ -1005,7 +1016,7 @@ all:: $(TEST_PROGRAMS)
export NO_SVN_TESTS
-check: common-cmds.h
+check: $(OUTPUT)common-cmds.h
if sparse; \
then \
for i in *.c */*.c; \
@@ -1039,10 +1050,10 @@ export perfexec_instdir
install: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
- $(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
+ $(INSTALL) $(OUTPUT)perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
- $(INSTALL) perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+ $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
$(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
$(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
@@ -1056,7 +1067,7 @@ ifdef BUILT_INS
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
ifneq (,$X)
- $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
+ $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) $(OUTPUT)perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
endif
endif
@@ -1140,14 +1151,14 @@ clean:
$(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
$(RM) $(TEST_PROGRAMS)
- $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
+ $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
$(RM) -r autom4te.cache
$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
$(RM) -r $(PERF_TARNAME) .doc-tmp-dir
$(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz
$(RM) $(htmldocs).tar.gz $(manpages).tar.gz
$(MAKE) -C Documentation/ clean
- $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS
+ $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-BUILD-OPTIONS
.PHONY: all install clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 8977317..52e646e 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -10,7 +10,6 @@
#include "../perf.h"
#include "../util/util.h"
#include "../util/parse-options.h"
-#include "../util/string.h"
#include "../util/header.h"
#include "bench.h"
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 887e8e0..ee0d917 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -14,7 +14,6 @@
#include "util/cache.h"
#include <linux/rbtree.h>
#include "util/symbol.h"
-#include "util/string.h"
#include "perf.h"
#include "util/debug.h"
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 924a951..513aa8a 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -363,19 +363,21 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
struct alloc_stat *data = rb_entry(next, struct alloc_stat,
node);
struct symbol *sym = NULL;
+ struct map *map;
char buf[BUFSIZ];
u64 addr;
if (is_caller) {
addr = data->call_site;
if (!raw_ip)
- sym = map_groups__find_function(&session->kmaps, addr, NULL);
+ sym = map_groups__find_function(&session->kmaps,
+ addr, &map, NULL);
} else
addr = data->ptr;
if (sym != NULL)
snprintf(buf, sizeof(buf), "%s+%Lx", sym->name,
- addr - sym->start);
+ addr - map->unmap_ip(map, sym->start));
else
snprintf(buf, sizeof(buf), "%#Lx", addr);
printf(" %-34s |", buf);
@@ -488,6 +490,9 @@ static int __cmd_kmem(void)
if (session == NULL)
return -ENOMEM;
+ if (perf_session__create_kernel_maps(session) < 0)
+ goto out_delete;
+
if (!perf_session__has_traces(session, "kmem record"))
goto out_delete;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 60ecdd3..dc61f1b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -15,7 +15,6 @@
#include "util/util.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
-#include "util/string.h"
#include "util/header.h"
#include "util/event.h"
@@ -575,6 +574,9 @@ static int __cmd_record(int argc, const char **argv)
err = event__synthesize_kernel_mmap(process_synthesized_event,
session, "_text");
+ if (err < 0)
+ err = event__synthesize_kernel_mmap(process_synthesized_event,
+ session, "_stext");
if (err < 0) {
pr_err("Couldn't record kernel reference relocation symbol.\n");
return err;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 6ab1698..e93c69a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -14,7 +14,6 @@
#include "util/cache.h"
#include <linux/rbtree.h>
#include "util/symbol.h"
-#include "util/string.h"
#include "util/callchain.h"
#include "util/strlist.h"
#include "util/values.h"
@@ -89,9 +88,12 @@ static int perf_session__add_hist_entry(struct perf_session *self,
struct event_stat_id *stats;
struct perf_event_attr *attr;
- if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain)
+ if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) {
syms = perf_session__resolve_callchain(self, al->thread,
data->callchain, &parent);
+ if (syms == NULL)
+ return -ENOMEM;
+ }
attr = perf_header__find_attr(data->id, &self->header);
if (attr)
@@ -110,8 +112,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
if (symbol_conf.use_callchain) {
if (!hit)
- callchain_init(&he->callchain);
- err = append_chain(&he->callchain, data->callchain, syms);
+ callchain_init(he->callchain);
+ err = append_chain(he->callchain, data->callchain, syms);
free(syms);
if (err)
@@ -303,14 +305,16 @@ static int __cmd_report(void)
next = rb_first(&session->stats_by_id);
while (next) {
struct event_stat_id *stats;
+ u64 nr_hists;
stats = rb_entry(next, struct event_stat_id, rb_node);
perf_session__collapse_resort(&stats->hists);
- perf_session__output_resort(&stats->hists, stats->stats.total);
-
+ nr_hists = perf_session__output_resort(&stats->hists,
+ stats->stats.total);
if (use_browser)
- perf_session__browse_hists(&stats->hists,
- stats->stats.total, help);
+ perf_session__browse_hists(&stats->hists, nr_hists,
+ stats->stats.total, help,
+ input_name);
else {
if (rb_first(&session->stats_by_id) ==
rb_last(&session->stats_by_id))
@@ -469,7 +473,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
setup_sorting(report_usage, options);
if (parent_pattern != default_parent_pattern) {
- sort_dimension__add("parent");
+ if (sort_dimension__add("parent") < 0)
+ return -1;
sort_parent.elide = 1;
} else
symbol_conf.exclude_other = false;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 0d4d8ff..266e7aa 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -21,7 +21,6 @@
#include "util/cache.h"
#include <linux/rbtree.h>
#include "util/symbol.h"
-#include "util/string.h"
#include "util/callchain.h"
#include "util/strlist.h"
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 2826e70..d4be55b 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -13,7 +13,6 @@
#include "util/quote.h"
#include "util/run-command.h"
#include "util/parse-events.h"
-#include "util/string.h"
#include "util/debugfs.h"
bool use_browser;
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 54552a0..49ece79 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -1,6 +1,10 @@
#!/bin/sh
-GVF=PERF-VERSION-FILE
+if [ $# -eq 1 ] ; then
+ OUTPUT=$1
+fi
+
+GVF=${OUTPUT}PERF-VERSION-FILE
DEF_VER=v0.0.2.PERF
LF='
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 9da0191..e191eb9 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -166,6 +166,31 @@ int perf_color_default_config(const char *var, const char *value, void *cb)
return perf_default_config(var, value, cb);
}
+static int __color_vsnprintf(char *bf, size_t size, const char *color,
+ const char *fmt, va_list args, const char *trail)
+{
+ int r = 0;
+
+ /*
+ * Auto-detect:
+ */
+ if (perf_use_color_default < 0) {
+ if (isatty(1) || pager_in_use())
+ perf_use_color_default = 1;
+ else
+ perf_use_color_default = 0;
+ }
+
+ if (perf_use_color_default && *color)
+ r += snprintf(bf, size, "%s", color);
+ r += vsnprintf(bf + r, size - r, fmt, args);
+ if (perf_use_color_default && *color)
+ r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
+ if (trail)
+ r += snprintf(bf + r, size - r, "%s", trail);
+ return r;
+}
+
static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
va_list args, const char *trail)
{
@@ -191,11 +216,28 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
return r;
}
+int color_vsnprintf(char *bf, size_t size, const char *color,
+ const char *fmt, va_list args)
+{
+ return __color_vsnprintf(bf, size, color, fmt, args, NULL);
+}
+
int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
{
return __color_vfprintf(fp, color, fmt, args, NULL);
}
+int color_snprintf(char *bf, size_t size, const char *color,
+ const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+ va_start(args, fmt);
+ r = color_vsnprintf(bf, size, color, fmt, args);
+ va_end(args);
+ return r;
+}
int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
{
@@ -203,10 +245,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
int r;
va_start(args, fmt);
- if (use_browser)
- r = vfprintf(fp, fmt, args);
- else
- r = color_vfprintf(fp, color, fmt, args);
+ r = color_vfprintf(fp, color, fmt, args);
va_end(args);
return r;
}
@@ -277,3 +316,9 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
return r;
}
+
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
+{
+ const char *color = get_percent_color(percent);
+ return color_snprintf(bf, size, color, fmt, percent);
+}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index 24e8809..dea082b 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -32,10 +32,14 @@ int perf_color_default_config(const char *var, const char *value, void *cb);
int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty);
void color_parse(const char *value, const char *var, char *dst);
void color_parse_mem(const char *value, int len, const char *var, char *dst);
+int color_vsnprintf(char *bf, size_t size, const char *color,
+ const char *fmt, va_list args);
int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args);
int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
+int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
const char *get_percent_color(double percent);
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 0172edf..5cb0a1b 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -10,13 +10,29 @@ extern int dump_trace;
int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void trace_event(event_t *event);
+struct ui_progress;
+
#ifdef NO_NEWT_SUPPORT
static inline int browser__show_help(const char *format __used, va_list ap __used)
{
return 0;
}
+
+static inline struct ui_progress *ui_progress__new(const char *title __used,
+ u64 total __used)
+{
+ return (struct ui_progress *)1;
+}
+
+static inline void ui_progress__update(struct ui_progress *self __used,
+ u64 curr __used) {}
+
+static inline void ui_progress__delete(struct ui_progress *self __used) {}
#else
int browser__show_help(const char *format, va_list ap);
+struct ui_progress *ui_progress__new(const char *title, u64 total);
+void ui_progress__update(struct ui_progress *self, u64 curr);
+void ui_progress__delete(struct ui_progress *self);
#endif
#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 052eaec..571fb25 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -130,6 +130,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
continue;
pbf += n + 3;
if (*pbf == 'x') { /* vm_exec */
+ u64 vm_pgoff;
char *execname = strchr(bf, '/');
/* Catch VDSO */
@@ -139,6 +140,14 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
if (execname == NULL)
continue;
+ pbf += 3;
+ n = hex2u64(pbf, &vm_pgoff);
+ /* pgoff is in bytes, not pages */
+ if (n >= 0)
+ ev.mmap.pgoff = vm_pgoff << getpagesize();
+ else
+ ev.mmap.pgoff = 0;
+
size = strlen(execname);
execname[size - 1] = '\0'; /* Remove \n */
memcpy(ev.mmap.filename, execname, size);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 09e09e7..18cf8b3 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -50,7 +50,8 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
p = &(*p)->rb_right;
}
- he = malloc(sizeof(*he));
+ he = malloc(sizeof(*he) + (symbol_conf.use_callchain ?
+ sizeof(struct callchain_node) : 0));
if (!he)
return NULL;
*he = entry;
@@ -168,7 +169,7 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
struct hist_entry *iter;
if (symbol_conf.use_callchain)
- callchain_param.sort(&he->sorted_chain, &he->callchain,
+ callchain_param.sort(&he->sorted_chain, he->callchain,
min_callchain_hits, &callchain_param);
while (*p != NULL) {
@@ -185,12 +186,13 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
rb_insert_color(&he->rb_node, root);
}
-void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
+u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples)
{
struct rb_root tmp;
struct rb_node *next;
struct hist_entry *n;
u64 min_callchain_hits;
+ u64 nr_hists = 0;
min_callchain_hits =
total_samples * (callchain_param.min_percent / 100);
@@ -205,9 +207,11 @@ void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
rb_erase(&n->rb_node, hists);
perf_session__insert_output_hist_entry(&tmp, n,
min_callchain_hits);
+ ++nr_hists;
}
*hists = tmp;
+ return nr_hists;
}
static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -452,16 +456,17 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
return ret;
}
-size_t hist_entry__fprintf(struct hist_entry *self,
+int hist_entry__snprintf(struct hist_entry *self,
+ char *s, size_t size,
struct perf_session *pair_session,
bool show_displacement,
- long displacement, FILE *fp,
+ long displacement, bool color,
u64 session_total)
{
struct sort_entry *se;
u64 count, total;
const char *sep = symbol_conf.field_sep;
- size_t ret;
+ int ret;
if (symbol_conf.exclude_other && !self->parent)
return 0;
@@ -474,17 +479,22 @@ size_t hist_entry__fprintf(struct hist_entry *self,
total = session_total;
}
- if (total)
- ret = percent_color_fprintf(fp, sep ? "%.2f" : " %6.2f%%",
- (count * 100.0) / total);
- else
- ret = fprintf(fp, sep ? "%lld" : "%12lld ", count);
+ if (total) {
+ if (color)
+ ret = percent_color_snprintf(s, size,
+ sep ? "%.2f" : " %6.2f%%",
+ (count * 100.0) / total);
+ else
+ ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%",
+ (count * 100.0) / total);
+ } else
+ ret = snprintf(s, size, sep ? "%lld" : "%12lld ", count);
if (symbol_conf.show_nr_samples) {
if (sep)
- ret += fprintf(fp, "%c%lld", *sep, count);
+ ret += snprintf(s + ret, size - ret, "%c%lld", *sep, count);
else
- ret += fprintf(fp, "%11lld", count);
+ ret += snprintf(s + ret, size - ret, "%11lld", count);
}
if (pair_session) {
@@ -504,9 +514,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
snprintf(bf, sizeof(bf), " ");
if (sep)
- ret += fprintf(fp, "%c%s", *sep, bf);
+ ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
else
- ret += fprintf(fp, "%11.11s", bf);
+ ret += snprintf(s + ret, size - ret, "%11.11s", bf);
if (show_displacement) {
if (displacement)
@@ -515,9 +525,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
snprintf(bf, sizeof(bf), " ");
if (sep)
- ret += fprintf(fp, "%c%s", *sep, bf);
+ ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
else
- ret += fprintf(fp, "%6.6s", bf);
+ ret += snprintf(s + ret, size - ret, "%6.6s", bf);
}
}
@@ -525,11 +535,25 @@ size_t hist_entry__fprintf(struct hist_entry *self,
if (se->elide)
continue;
- ret += fprintf(fp, "%s", sep ?: " ");
- ret += se->print(fp, self, se->width ? *se->width : 0);
+ ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
+ ret += se->snprintf(self, s + ret, size - ret,
+ se->width ? *se->width : 0);
}
- return ret + fprintf(fp, "\n");
+ return ret;
+}
+
+int hist_entry__fprintf(struct hist_entry *self,
+ struct perf_session *pair_session,
+ bool show_displacement,
+ long displacement, FILE *fp,
+ u64 session_total)
+{
+ char bf[512];
+ hist_entry__snprintf(self, bf, sizeof(bf), pair_session,
+ show_displacement, displacement,
+ true, session_total);
+ return fprintf(fp, "%s\n", bf);
}
static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
@@ -658,7 +682,7 @@ print_entries:
if (h->ms.map == NULL && verbose > 1) {
__map_groups__fprintf_maps(&h->thread->mg,
- MAP__FUNCTION, fp);
+ MAP__FUNCTION, verbose, fp);
fprintf(fp, "%.10s end\n", graph_dotted_line);
}
}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index fe366ce..ad17f0a 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -18,14 +18,19 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
u64 count, bool *hit);
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
-size_t hist_entry__fprintf(struct hist_entry *self,
+int hist_entry__fprintf(struct hist_entry *self,
struct perf_session *pair_session,
bool show_displacement,
long displacement, FILE *fp,
u64 session_total);
+int hist_entry__snprintf(struct hist_entry *self,
+ char *bf, size_t size,
+ struct perf_session *pair_session,
+ bool show_displacement, long displacement,
+ bool color, u64 session_total);
void hist_entry__free(struct hist_entry *);
-void perf_session__output_resort(struct rb_root *hists, u64 total_samples);
+u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples);
void perf_session__collapse_resort(struct rb_root *hists);
size_t perf_session__fprintf_hists(struct rb_root *hists,
struct perf_session *pair,
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 9f2963f..37913b2 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -1,4 +1,5 @@
#include "symbol.h"
+#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -234,18 +235,211 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
return ip;
}
+void map_groups__init(struct map_groups *self)
+{
+ int i;
+ for (i = 0; i < MAP__NR_TYPES; ++i) {
+ self->maps[i] = RB_ROOT;
+ INIT_LIST_HEAD(&self->removed_maps[i]);
+ }
+}
+
+void map_groups__flush(struct map_groups *self)
+{
+ int type;
+
+ for (type = 0; type < MAP__NR_TYPES; type++) {
+ struct rb_root *root = &self->maps[type];
+ struct rb_node *next = rb_first(root);
+
+ while (next) {
+ struct map *pos = rb_entry(next, struct map, rb_node);
+ next = rb_next(&pos->rb_node);
+ rb_erase(&pos->rb_node, root);
+ /*
+ * We may have references to this map, for
+ * instance in some hist_entry instances, so
+ * just move them to a separate list.
+ */
+ list_add_tail(&pos->node, &self->removed_maps[pos->type]);
+ }
+ }
+}
+
struct symbol *map_groups__find_symbol(struct map_groups *self,
enum map_type type, u64 addr,
+ struct map **mapp,
symbol_filter_t filter)
{
struct map *map = map_groups__find(self, type, addr);
- if (map != NULL)
+ if (map != NULL) {
+ if (mapp != NULL)
+ *mapp = map;
return map__find_symbol(map, map->map_ip(map, addr), filter);
+ }
return NULL;
}
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+ enum map_type type,
+ const char *name,
+ struct map **mapp,
+ symbol_filter_t filter)
+{
+ struct rb_node *nd;
+
+ for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+ struct map *pos = rb_entry(nd, struct map, rb_node);
+ struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
+
+ if (sym == NULL)
+ continue;
+ if (mapp != NULL)
+ *mapp = pos;
+ return sym;
+ }
+
+ return NULL;
+}
+
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+ enum map_type type, int verbose, FILE *fp)
+{
+ size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
+ struct rb_node *nd;
+
+ for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+ struct map *pos = rb_entry(nd, struct map, rb_node);
+ printed += fprintf(fp, "Map:");
+ printed += map__fprintf(pos, fp);
+ if (verbose > 2) {
+ printed += dso__fprintf(pos->dso, type, fp);
+ printed += fprintf(fp, "--\n");
+ }
+ }
+
+ return printed;
+}
+
+size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp)
+{
+ size_t printed = 0, i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ printed += __map_groups__fprintf_maps(self, i, verbose, fp);
+ return printed;
+}
+
+static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
+ enum map_type type,
+ int verbose, FILE *fp)
+{
+ struct map *pos;
+ size_t printed = 0;
+
+ list_for_each_entry(pos, &self->removed_maps[type], node) {
+ printed += fprintf(fp, "Map:");
+ printed += map__fprintf(pos, fp);
+ if (verbose > 1) {
+ printed += dso__fprintf(pos->dso, type, fp);
+ printed += fprintf(fp, "--\n");
+ }
+ }
+ return printed;
+}
+
+static size_t map_groups__fprintf_removed_maps(struct map_groups *self,
+ int verbose, FILE *fp)
+{
+ size_t printed = 0, i;
+ for (i = 0; i < MAP__NR_TYPES; ++i)
+ printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp);
+ return printed;
+}
+
+size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp)
+{
+ size_t printed = map_groups__fprintf_maps(self, verbose, fp);
+ printed += fprintf(fp, "Removed maps:\n");
+ return printed + map_groups__fprintf_removed_maps(self, verbose, fp);
+}
+
+int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+ int verbose, FILE *fp)
+{
+ struct rb_root *root = &self->maps[map->type];
+ struct rb_node *next = rb_first(root);
+
+ while (next) {
+ struct map *pos = rb_entry(next, struct map, rb_node);
+ next = rb_next(&pos->rb_node);
+
+ if (!map__overlap(pos, map))
+ continue;
+
+ if (verbose >= 2) {
+ fputs("overlapping maps:\n", fp);
+ map__fprintf(map, fp);
+ map__fprintf(pos, fp);
+ }
+
+ rb_erase(&pos->rb_node, root);
+ /*
+ * We may have references to this map, for instance in some
+ * hist_entry instances, so just move them to a separate
+ * list.
+ */
+ list_add_tail(&pos->node, &self->removed_maps[map->type]);
+ /*
+ * Now check if we need to create new maps for areas not
+ * overlapped by the new map:
+ */
+ if (map->start > pos->start) {
+ struct map *before = map__clone(pos);
+
+ if (before == NULL)
+ return -ENOMEM;
+
+ before->end = map->start - 1;
+ map_groups__insert(self, before);
+ if (verbose >= 2)
+ map__fprintf(before, fp);
+ }
+
+ if (map->end < pos->end) {
+ struct map *after = map__clone(pos);
+
+ if (after == NULL)
+ return -ENOMEM;
+
+ after->start = map->end + 1;
+ map_groups__insert(self, after);
+ if (verbose >= 2)
+ map__fprintf(after, fp);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * XXX This should not really _copy_ te maps, but refcount them.
+ */
+int map_groups__clone(struct map_groups *self,
+ struct map_groups *parent, enum map_type type)
+{
+ struct rb_node *nd;
+ for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
+ struct map *map = rb_entry(nd, struct map, rb_node);
+ struct map *new = map__clone(map);
+ if (new == NULL)
+ return -ENOMEM;
+ map_groups__insert(self, new);
+ }
+ return 0;
+}
+
static u64 map__reloc_map_ip(struct map *map, u64 ip)
{
return ip + (s64)map->pgoff;
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 6a703fa..2031278 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -97,11 +97,14 @@ struct map_groups {
};
size_t __map_groups__fprintf_maps(struct map_groups *self,
- enum map_type type, FILE *fp);
+ enum map_type type, int verbose, FILE *fp);
void maps__insert(struct rb_root *maps, struct map *map);
struct map *maps__find(struct rb_root *maps, u64 addr);
void map_groups__init(struct map_groups *self);
-size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp);
+int map_groups__clone(struct map_groups *self,
+ struct map_groups *parent, enum map_type type);
+size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
+size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp);
static inline void map_groups__insert(struct map_groups *self, struct map *map)
{
@@ -116,15 +119,33 @@ static inline struct map *map_groups__find(struct map_groups *self,
struct symbol *map_groups__find_symbol(struct map_groups *self,
enum map_type type, u64 addr,
+ struct map **mapp,
symbol_filter_t filter);
-static inline struct symbol *map_groups__find_function(struct map_groups *self,
- u64 addr,
- symbol_filter_t filter)
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+ enum map_type type,
+ const char *name,
+ struct map **mapp,
+ symbol_filter_t filter);
+
+static inline
+struct symbol *map_groups__find_function(struct map_groups *self, u64 addr,
+ struct map **mapp, symbol_filter_t filter)
{
- return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter);
+ return map_groups__find_symbol(self, MAP__FUNCTION, addr, mapp, filter);
}
+static inline
+struct symbol *map_groups__find_function_by_name(struct map_groups *self,
+ const char *name, struct map **mapp,
+ symbol_filter_t filter)
+{
+ return map_groups__find_symbol_by_name(self, MAP__FUNCTION, name, mapp, filter);
+}
+
+int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+ int verbose, FILE *fp);
+
struct map *map_groups__find_by_name(struct map_groups *self,
enum map_type type, const char *name);
int __map_groups__create_kernel_maps(struct map_groups *self,
@@ -134,5 +155,6 @@ int map_groups__create_kernel_maps(struct map_groups *self,
struct map *vmlinux_maps[MAP__NR_TYPES]);
struct map *map_groups__new_module(struct map_groups *self, u64 start,
const char *filename);
+void map_groups__flush(struct map_groups *self);
#endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index e99bcc8..c93bc2a 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -12,6 +12,72 @@
#include "sort.h"
#include "symbol.h"
+struct ui_progress {
+ newtComponent form, scale;
+};
+
+struct ui_progress *ui_progress__new(const char *title, u64 total)
+{
+ struct ui_progress *self = malloc(sizeof(*self));
+
+ if (self != NULL) {
+ int cols;
+ newtGetScreenSize(&cols, NULL);
+ cols -= 4;
+ newtCenteredWindow(cols, 1, title);
+ self->form = newtForm(NULL, NULL, 0);
+ if (self->form == NULL)
+ goto out_free_self;
+ self->scale = newtScale(0, 0, cols, total);
+ if (self->scale == NULL)
+ goto out_free_form;
+ newtFormAddComponents(self->form, self->scale, NULL);
+ newtRefresh();
+ }
+
+ return self;
+
+out_free_form:
+ newtFormDestroy(self->form);
+out_free_self:
+ free(self);
+ return NULL;
+}
+
+void ui_progress__update(struct ui_progress *self, u64 curr)
+{
+ newtScaleSet(self->scale, curr);
+ newtRefresh();
+}
+
+void ui_progress__delete(struct ui_progress *self)
+{
+ newtFormDestroy(self->form);
+ newtPopWindow();
+ free(self);
+}
+
+static char browser__last_msg[1024];
+
+int browser__show_help(const char *format, va_list ap)
+{
+ int ret;
+ static int backlog;
+
+ ret = vsnprintf(browser__last_msg + backlog,
+ sizeof(browser__last_msg) - backlog, format, ap);
+ backlog += ret;
+
+ if (browser__last_msg[backlog - 1] == '\n') {
+ newtPopHelpLine();
+ newtPushHelpLine(browser__last_msg);
+ newtRefresh();
+ backlog = 0;
+ }
+
+ return ret;
+}
+
static void newt_form__set_exit_keys(newtComponent self)
{
newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
@@ -228,60 +294,17 @@ static void hist_entry__append_callchain_browser(struct hist_entry *self,
}
}
-/*
- * FIXME: get lib/string.c linked with perf somehow
- */
-static char *skip_spaces(const char *str)
-{
- while (isspace(*str))
- ++str;
- return (char *)str;
-}
-
-static char *strim(char *s)
-{
- size_t size;
- char *end;
-
- s = skip_spaces(s);
- size = strlen(s);
- if (!size)
- return s;
-
- end = s + size - 1;
- while (end >= s && isspace(*end))
- end--;
- *(end + 1) = '\0';
-
- return s;
-}
-
static size_t hist_entry__append_browser(struct hist_entry *self,
newtComponent tree, u64 total)
{
- char bf[1024], *s;
- FILE *fp;
+ char s[256];
+ size_t ret;
if (symbol_conf.exclude_other && !self->parent)
return 0;
- fp = fmemopen(bf, sizeof(bf), "w");
- if (fp == NULL)
- return 0;
-
- hist_entry__fprintf(self, NULL, false, 0, fp, total);
- fclose(fp);
-
- /*
- * FIXME: We shouldn't need to trim, as the printing routines shouldn't
- * add spaces it in the first place, the stdio output routines should
- * call a __snprintf method instead of the current __print (that
- * actually is a __fprintf) one, but get the raw string and _then_ add
- * the newline, as this is a detail of stdio printing, not needed in
- * other UIs, e.g. newt.
- */
- s = strim(bf);
-
+ ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
+ false, 0, false, total);
if (symbol_conf.use_callchain) {
int indexes[2];
@@ -291,10 +314,11 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
} else
newtListboxAppendEntry(tree, s, &self->ms);
- return strlen(s);
+ return ret;
}
-static void map_symbol__annotate_browser(const struct map_symbol *self)
+static void map_symbol__annotate_browser(const struct map_symbol *self,
+ const char *input_name)
{
FILE *fp;
int cols, rows;
@@ -308,8 +332,8 @@ static void map_symbol__annotate_browser(const struct map_symbol *self)
if (self->sym == NULL)
return;
- if (asprintf(&str, "perf annotate -d \"%s\" %s 2>&1 | expand",
- self->map->dso->name, self->sym->name) < 0)
+ if (asprintf(&str, "perf annotate -i \"%s\" -d \"%s\" %s 2>&1 | expand",
+ input_name, self->map->dso->name, self->sym->name) < 0)
return;
fp = popen(str, "r");
@@ -358,90 +382,121 @@ static const void *newt__symbol_tree_get_current(newtComponent self)
return newtListboxGetCurrent(self);
}
-static void perf_session__selection(newtComponent self, void *data)
+static void hist_browser__selection(newtComponent self, void *data)
{
const struct map_symbol **symbol_ptr = data;
*symbol_ptr = newt__symbol_tree_get_current(self);
}
-void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
- const char *helpline)
-{
- struct sort_entry *se;
- struct rb_node *nd;
- char seq[] = ".";
- unsigned int width;
- char *col_width = symbol_conf.col_width_list_str;
- int rows, cols, idx;
- int max_len = 0;
- char str[1024];
- newtComponent form, tree;
- struct newtExitStruct es;
+struct hist_browser {
+ newtComponent form, tree;
const struct map_symbol *selection;
+};
- snprintf(str, sizeof(str), "Samples: %Ld", session_total);
- newtDrawRootText(0, 0, str);
- newtPushHelpLine(helpline);
-
- newtGetScreenSize(&cols, &rows);
+static struct hist_browser *hist_browser__new(void)
+{
+ struct hist_browser *self = malloc(sizeof(*self));
- if (symbol_conf.use_callchain)
- tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
- NEWT_FLAG_SCROLL);
- else
- tree = newtListbox(0, 0, rows - 5, (NEWT_FLAG_SCROLL |
- NEWT_FLAG_RETURNEXIT));
+ if (self != NULL) {
+ char seq[] = ".";
+ int rows;
- newtComponentAddCallback(tree, perf_session__selection, &selection);
+ newtGetScreenSize(NULL, &rows);
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- if (se->elide)
- continue;
- width = strlen(se->header);
- if (se->width) {
- if (symbol_conf.col_width_list_str) {
- if (col_width) {
- *se->width = atoi(col_width);
- col_width = strchr(col_width, ',');
- if (col_width)
- ++col_width;
- }
- }
- *se->width = max(*se->width, width);
- }
+ if (symbol_conf.use_callchain)
+ self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
+ NEWT_FLAG_SCROLL);
+ else
+ self->tree = newtListbox(0, 0, rows - 5,
+ (NEWT_FLAG_SCROLL |
+ NEWT_FLAG_RETURNEXIT));
+ newtComponentAddCallback(self->tree, hist_browser__selection,
+ &self->selection);
}
+ return self;
+}
+
+static void hist_browser__delete(struct hist_browser *self)
+{
+ newtFormDestroy(self->form);
+ newtPopWindow();
+ free(self);
+}
+
+static int hist_browser__populate(struct hist_browser *self, struct rb_root *hists,
+ u64 nr_hists, u64 session_total)
+{
+ int max_len = 0, idx, cols, rows;
+ struct ui_progress *progress;
+ struct rb_node *nd;
+ u64 curr_hist = 0;
+
+ progress = ui_progress__new("Adding entries to the browser...", nr_hists);
+ if (progress == NULL)
+ return -1;
+
idx = 0;
for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
- int len = hist_entry__append_browser(h, tree, session_total);
+ int len = hist_entry__append_browser(h, self->tree, session_total);
if (len > max_len)
max_len = len;
if (symbol_conf.use_callchain)
- hist_entry__append_callchain_browser(h, tree, session_total, idx++);
+ hist_entry__append_callchain_browser(h, self->tree,
+ session_total, idx++);
+ ++curr_hist;
+ if (curr_hist % 5)
+ ui_progress__update(progress, curr_hist);
}
+ ui_progress__delete(progress);
+
+ newtGetScreenSize(&cols, &rows);
+
if (max_len > cols)
max_len = cols - 3;
if (!symbol_conf.use_callchain)
- newtListboxSetWidth(tree, max_len);
+ newtListboxSetWidth(self->tree, max_len);
newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
rows - 5, "Report");
- form = newt_form__new();
- newtFormAddHotKey(form, 'A');
- newtFormAddHotKey(form, 'a');
- newtFormAddHotKey(form, NEWT_KEY_RIGHT);
- newtFormAddComponents(form, tree, NULL);
- selection = newt__symbol_tree_get_current(tree);
+ self->form = newt_form__new();
+ newtFormAddHotKey(self->form, 'A');
+ newtFormAddHotKey(self->form, 'a');
+ newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
+ newtFormAddComponents(self->form, self->tree, NULL);
+ self->selection = newt__symbol_tree_get_current(self->tree);
+
+ return 0;
+}
+
+int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
+ u64 session_total, const char *helpline,
+ const char *input_name)
+{
+ struct newtExitStruct es;
+ char str[1024];
+ int err = -1;
+ struct hist_browser *browser = hist_browser__new();
+
+ if (browser == NULL)
+ return -1;
+
+ snprintf(str, sizeof(str), "Samples: %Ld", session_total);
+ newtDrawRootText(0, 0, str);
+ newtPushHelpLine(helpline);
+
+ if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
+ goto out;
while (1) {
char annotate[512];
const char *options[2];
int nr_options = 0, choice = 0;
- newtFormRun(form, &es);
+ newtFormRun(browser->form, &es);
if (es.reason == NEWT_EXIT_HOTKEY) {
if (toupper(es.u.key) == 'A')
goto do_annotate;
@@ -455,9 +510,9 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
}
}
- if (selection->sym != NULL) {
+ if (browser->selection->sym != NULL) {
snprintf(annotate, sizeof(annotate),
- "Annotate %s", selection->sym->name);
+ "Annotate %s", browser->selection->sym->name);
options[nr_options++] = annotate;
}
@@ -466,41 +521,22 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
if (choice == nr_options - 1)
break;
do_annotate:
- if (selection->sym != NULL && choice >= 0) {
- if (selection->map->dso->origin == DSO__ORIG_KERNEL) {
+ if (browser->selection->sym != NULL && choice >= 0) {
+ if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
newtPopHelpLine();
newtPushHelpLine("No vmlinux file found, can't "
"annotate with just a "
"kallsyms file");
continue;
}
- map_symbol__annotate_browser(selection);
+ map_symbol__annotate_browser(browser->selection,
+ input_name);
}
}
-
- newtFormDestroy(form);
- newtPopWindow();
-}
-
-static char browser__last_msg[1024];
-
-int browser__show_help(const char *format, va_list ap)
-{
- int ret;
- static int backlog;
-
- ret = vsnprintf(browser__last_msg + backlog,
- sizeof(browser__last_msg) - backlog, format, ap);
- backlog += ret;
-
- if (browser__last_msg[backlog - 1] == '\n') {
- newtPopHelpLine();
- newtPushHelpLine(browser__last_msg);
- newtRefresh();
- backlog = 0;
- }
-
- return ret;
+ err = 0;
+out:
+ hist_browser__delete(browser);
+ return err;
}
void setup_browser(void)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 76b4ac6..ddf288f 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -52,11 +52,6 @@ out_close:
return -1;
}
-static inline int perf_session__create_kernel_maps(struct perf_session *self)
-{
- return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
-}
-
struct perf_session *perf_session__new(const char *filename, int mode, bool force)
{
size_t len = filename ? strlen(filename) + 1 : 0;
@@ -123,16 +118,11 @@ struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
struct symbol **parent)
{
u8 cpumode = PERF_RECORD_MISC_USER;
- struct map_symbol *syms = NULL;
unsigned int i;
+ struct map_symbol *syms = calloc(chain->nr, sizeof(*syms));
- if (symbol_conf.use_callchain) {
- syms = calloc(chain->nr, sizeof(*syms));
- if (!syms) {
- fprintf(stderr, "Can't allocate memory for symbols\n");
- exit(-1);
- }
- }
+ if (!syms)
+ return NULL;
for (i = 0; i < chain->nr; i++) {
u64 ip = chain->ips[i];
@@ -397,6 +387,10 @@ int __perf_session__process_events(struct perf_session *self,
event_t *event;
uint32_t size;
char *buf;
+ struct ui_progress *progress = ui_progress__new("Processing events...",
+ self->size);
+ if (progress == NULL)
+ return -1;
perf_event_ops__fill_defaults(ops);
@@ -425,6 +419,7 @@ remap:
more:
event = (event_t *)(buf + head);
+ ui_progress__update(progress, offset);
if (self->header.needs_swap)
perf_event_header__bswap(&event->header);
@@ -475,6 +470,7 @@ more:
done:
err = 0;
out_err:
+ ui_progress__delete(progress);
return err;
}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 631f815..27f4c2d 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -80,6 +80,11 @@ static inline int __perf_session__create_kernel_maps(struct perf_session *self,
self->vmlinux_maps, kernel);
}
+static inline int perf_session__create_kernel_maps(struct perf_session *self)
+{
+ return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
+}
+
static inline struct map *
perf_session__new_module_map(struct perf_session *self,
u64 start, const char *filename)
@@ -88,11 +93,17 @@ static inline struct map *
}
#ifdef NO_NEWT_SUPPORT
-static inline void perf_session__browse_hists(struct rb_root *hists __used,
+static inline int perf_session__browse_hists(struct rb_root *hists __used,
+ u64 nr_hists __used,
u64 session_total __used,
- const char *helpline __used) {}
+ const char *helpline __used,
+ const char *input_name __used)
+{
+ return 0;
+}
#else
-void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
- const char *helpline);
+int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
+ u64 session_total, const char *helpline,
+ const char *input_name);
#endif
#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9b80c13..9d24d4b 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -18,10 +18,21 @@ char * field_sep;
LIST_HEAD(hist_entry__sort_list);
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width);
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width);
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width);
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width);
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width);
+
struct sort_entry sort_thread = {
.header = "Command: Pid",
.cmp = sort__thread_cmp,
- .print = sort__thread_print,
+ .snprintf = hist_entry__thread_snprintf,
.width = &threads__col_width,
};
@@ -29,27 +40,27 @@ struct sort_entry sort_comm = {
.header = "Command",
.cmp = sort__comm_cmp,
.collapse = sort__comm_collapse,
- .print = sort__comm_print,
+ .snprintf = hist_entry__comm_snprintf,
.width = &comms__col_width,
};
struct sort_entry sort_dso = {
.header = "Shared Object",
.cmp = sort__dso_cmp,
- .print = sort__dso_print,
+ .snprintf = hist_entry__dso_snprintf,
.width = &dsos__col_width,
};
struct sort_entry sort_sym = {
.header = "Symbol",
.cmp = sort__sym_cmp,
- .print = sort__sym_print,
+ .snprintf = hist_entry__sym_snprintf,
};
struct sort_entry sort_parent = {
.header = "Parent symbol",
.cmp = sort__parent_cmp,
- .print = sort__parent_print,
+ .snprintf = hist_entry__parent_snprintf,
.width = &parent_symbol__col_width,
};
@@ -85,45 +96,38 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
return right->thread->pid - left->thread->pid;
}
-int repsep_fprintf(FILE *fp, const char *fmt, ...)
+static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
{
int n;
va_list ap;
va_start(ap, fmt);
- if (!field_sep)
- n = vfprintf(fp, fmt, ap);
- else {
- char *bf = NULL;
- n = vasprintf(&bf, fmt, ap);
- if (n > 0) {
- char *sep = bf;
-
- while (1) {
- sep = strchr(sep, *field_sep);
- if (sep == NULL)
- break;
- *sep = '.';
- }
+ n = vsnprintf(bf, size, fmt, ap);
+ if (field_sep && n > 0) {
+ char *sep = bf;
+
+ while (1) {
+ sep = strchr(sep, *field_sep);
+ if (sep == NULL)
+ break;
+ *sep = '.';
}
- fputs(bf, fp);
- free(bf);
}
va_end(ap);
return n;
}
-size_t
-sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
{
- return repsep_fprintf(fp, "%*s:%5d", width - 6,
+ return repsep_snprintf(bf, size, "%*s:%5d", width,
self->thread->comm ?: "", self->thread->pid);
}
-size_t
-sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
{
- return repsep_fprintf(fp, "%*s", width, self->thread->comm);
+ return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
}
/* --sort dso */
@@ -149,16 +153,16 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(dso_name_l, dso_name_r);
}
-size_t
-sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
{
if (self->ms.map && self->ms.map->dso) {
const char *dso_name = !verbose ? self->ms.map->dso->short_name :
self->ms.map->dso->long_name;
- return repsep_fprintf(fp, "%-*s", width, dso_name);
+ return repsep_snprintf(bf, size, "%-*s", width, dso_name);
}
- return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
+ return repsep_snprintf(bf, size, "%*Lx", width, self->ip);
}
/* --sort symbol */
@@ -177,22 +181,22 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
return (int64_t)(ip_r - ip_l);
}
-
-size_t
-sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width __used)
{
size_t ret = 0;
if (verbose) {
char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!';
- ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, o);
+ ret += repsep_snprintf(bf, size, "%#018llx %c ", self->ip, o);
}
- ret += repsep_fprintf(fp, "[%c] ", self->level);
+ ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level);
if (self->ms.sym)
- ret += repsep_fprintf(fp, "%s", self->ms.sym->name);
+ ret += repsep_snprintf(bf + ret, size - ret, "%s",
+ self->ms.sym->name);
else
- ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
+ ret += repsep_snprintf(bf + ret, size - ret, "%#016llx", self->ip);
return ret;
}
@@ -231,10 +235,10 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(sym_l->name, sym_r->name);
}
-size_t
-sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
{
- return repsep_fprintf(fp, "%-*s", width,
+ return repsep_snprintf(bf, size, "%-*s", width,
self->parent ? self->parent->name : "[other]");
}
@@ -260,9 +264,8 @@ int sort_dimension__add(const char *tok)
char err[BUFSIZ];
regerror(ret, &parent_regex, err, sizeof(err));
- fprintf(stderr, "Invalid regex: %s\n%s",
- parent_pattern, err);
- exit(-1);
+ pr_err("Invalid regex: %s\n%s", parent_pattern, err);
+ return -EINVAL;
}
sort__has_parent = 1;
}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 5985686..5bf2b74 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -49,12 +49,12 @@ struct hist_entry {
u64 ip;
char level;
struct symbol *parent;
- struct callchain_node callchain;
union {
unsigned long position;
struct hist_entry *pair;
struct rb_root sorted_chain;
};
+ struct callchain_node callchain[0];
};
enum sort_type {
@@ -76,7 +76,8 @@ struct sort_entry {
int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
- size_t (*print)(FILE *fp, struct hist_entry *, unsigned int width);
+ int (*snprintf)(struct hist_entry *self, char *bf, size_t size,
+ unsigned int width);
unsigned int *width;
bool elide;
};
@@ -86,7 +87,6 @@ extern struct list_head hist_entry__sort_list;
void setup_sorting(const char * const usagestr[], const struct option *opts);
-extern int repsep_fprintf(FILE *fp, const char *fmt, ...);
extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int);
extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int);
extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int);
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h
deleted file mode 100644
index 7005824..0000000
--- a/tools/perf/util/string.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __PERF_STRING_H_
-#define __PERF_STRING_H_
-
-#include <stdbool.h>
-#include "types.h"
-
-s64 perf_atoll(const char *str);
-char **argv_split(const char *str, int *argcp);
-void argv_free(char **argv);
-bool strglobmatch(const char *str, const char *pat);
-bool strlazymatch(const char *str, const char *pat);
-
-#define _STR(x) #x
-#define STR(x) _STR(x)
-
-#endif /* __PERF_STRING_H */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 9bbe27d..1f7ecd4 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -38,15 +38,6 @@ failure:
return ret;
}
-void map_groups__init(struct map_groups *self)
-{
- int i;
- for (i = 0; i < MAP__NR_TYPES; ++i) {
- self->maps[i] = RB_ROOT;
- INIT_LIST_HEAD(&self->removed_maps[i]);
- }
-}
-
static struct thread *thread__new(pid_t pid)
{
struct thread *self = zalloc(sizeof(*self));
@@ -62,28 +53,6 @@ static struct thread *thread__new(pid_t pid)
return self;
}
-static void map_groups__flush(struct map_groups *self)
-{
- int type;
-
- for (type = 0; type < MAP__NR_TYPES; type++) {
- struct rb_root *root = &self->maps[type];
- struct rb_node *next = rb_first(root);
-
- while (next) {
- struct map *pos = rb_entry(next, struct map, rb_node);
- next = rb_next(&pos->rb_node);
- rb_erase(&pos->rb_node, root);
- /*
- * We may have references to this map, for
- * instance in some hist_entry instances, so
- * just move them to a separate list.
- */
- list_add_tail(&pos->node, &self->removed_maps[pos->type]);
- }
- }
-}
-
int thread__set_comm(struct thread *self, const char *comm)
{
int err;
@@ -110,69 +79,10 @@ int thread__comm_len(struct thread *self)
return self->comm_len;
}
-size_t __map_groups__fprintf_maps(struct map_groups *self,
- enum map_type type, FILE *fp)
-{
- size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
- struct rb_node *nd;
-
- for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
- struct map *pos = rb_entry(nd, struct map, rb_node);
- printed += fprintf(fp, "Map:");
- printed += map__fprintf(pos, fp);
- if (verbose > 2) {
- printed += dso__fprintf(pos->dso, type, fp);
- printed += fprintf(fp, "--\n");
- }
- }
-
- return printed;
-}
-
-size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp)
-{
- size_t printed = 0, i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- printed += __map_groups__fprintf_maps(self, i, fp);
- return printed;
-}
-
-static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
- enum map_type type, FILE *fp)
-{
- struct map *pos;
- size_t printed = 0;
-
- list_for_each_entry(pos, &self->removed_maps[type], node) {
- printed += fprintf(fp, "Map:");
- printed += map__fprintf(pos, fp);
- if (verbose > 1) {
- printed += dso__fprintf(pos->dso, type, fp);
- printed += fprintf(fp, "--\n");
- }
- }
- return printed;
-}
-
-static size_t map_groups__fprintf_removed_maps(struct map_groups *self, FILE *fp)
-{
- size_t printed = 0, i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- printed += __map_groups__fprintf_removed_maps(self, i, fp);
- return printed;
-}
-
-static size_t map_groups__fprintf(struct map_groups *self, FILE *fp)
-{
- size_t printed = map_groups__fprintf_maps(self, fp);
- printed += fprintf(fp, "Removed maps:\n");
- return printed + map_groups__fprintf_removed_maps(self, fp);
-}
-
static size_t thread__fprintf(struct thread *self, FILE *fp)
{
return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) +
- map_groups__fprintf(&self->mg, fp);
+ map_groups__fprintf(&self->mg, verbose, fp);
}
struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
@@ -214,87 +124,12 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
return th;
}
-static int map_groups__fixup_overlappings(struct map_groups *self,
- struct map *map)
-{
- struct rb_root *root = &self->maps[map->type];
- struct rb_node *next = rb_first(root);
-
- while (next) {
- struct map *pos = rb_entry(next, struct map, rb_node);
- next = rb_next(&pos->rb_node);
-
- if (!map__overlap(pos, map))
- continue;
-
- if (verbose >= 2) {
- fputs("overlapping maps:\n", stderr);
- map__fprintf(map, stderr);
- map__fprintf(pos, stderr);
- }
-
- rb_erase(&pos->rb_node, root);
- /*
- * We may have references to this map, for instance in some
- * hist_entry instances, so just move them to a separate
- * list.
- */
- list_add_tail(&pos->node, &self->removed_maps[map->type]);
- /*
- * Now check if we need to create new maps for areas not
- * overlapped by the new map:
- */
- if (map->start > pos->start) {
- struct map *before = map__clone(pos);
-
- if (before == NULL)
- return -ENOMEM;
-
- before->end = map->start - 1;
- map_groups__insert(self, before);
- if (verbose >= 2)
- map__fprintf(before, stderr);
- }
-
- if (map->end < pos->end) {
- struct map *after = map__clone(pos);
-
- if (after == NULL)
- return -ENOMEM;
-
- after->start = map->end + 1;
- map_groups__insert(self, after);
- if (verbose >= 2)
- map__fprintf(after, stderr);
- }
- }
-
- return 0;
-}
-
void thread__insert_map(struct thread *self, struct map *map)
{
- map_groups__fixup_overlappings(&self->mg, map);
+ map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
map_groups__insert(&self->mg, map);
}
-/*
- * XXX This should not really _copy_ te maps, but refcount them.
- */
-static int map_groups__clone(struct map_groups *self,
- struct map_groups *parent, enum map_type type)
-{
- struct rb_node *nd;
- for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
- struct map *map = rb_entry(nd, struct map, rb_node);
- struct map *new = map__clone(map);
- if (new == NULL)
- return -ENOMEM;
- map_groups__insert(self, new);
- }
- return 0;
-}
-
int thread__fork(struct thread *self, struct thread *parent)
{
int i;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 5270108..fbf45d1 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -42,12 +42,14 @@
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _BSD_SOURCE 1
+#define HAS_BOOL
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -78,6 +80,7 @@
#include <pwd.h>
#include <inttypes.h>
#include "../../../include/linux/magic.h"
+#include "types.h"
#ifndef NO_ICONV
@@ -415,4 +418,13 @@ void git_qsort(void *base, size_t nmemb, size_t size,
int mkdir_p(char *path, mode_t mode);
int copyfile(const char *from, const char *to);
+s64 perf_atoll(const char *str);
+char **argv_split(const char *str, int *argcp);
+void argv_free(char **argv);
+bool strglobmatch(const char *str, const char *pat);
+bool strlazymatch(const char *str, const char *pat);
+
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
#endif
OpenPOWER on IntegriCloud