Commit a12b51c478899fe0b7e874a559b05ba35f1128ee

Authored by Paul Mackerras
Committed by Ingo Molnar
1 parent 220b140b52

perf tools: Fix sparse CPU numbering related bugs

At present, the perf subcommands that do system-wide monitoring
(perf stat, perf record and perf top) don't work properly unless
the online cpus are numbered 0, 1, ..., N-1.  These tools ask
for the number of online cpus with sysconf(_SC_NPROCESSORS_ONLN)
and then try to create events for cpus 0, 1, ..., N-1.

This creates problems for systems where the online cpus are
numbered sparsely.  For example, a POWER6 system in
single-threaded mode (i.e. only running 1 hardware thread per
core) will have only even-numbered cpus online.

This fixes the problem by reading the /sys/devices/system/cpu/online
file to find out which cpus are online.  The code that does that is in
tools/perf/util/cpumap.[ch], and consists of a read_cpu_map()
function that sets up a cpumap[] array and returns the number of
online cpus.  If /sys/devices/system/cpu/online can't be read or
can't be parsed successfully, it falls back to using sysconf to
ask how many cpus are online and sets up an identity map in cpumap[].

The perf record, perf stat and perf top code then calls
read_cpu_map() in the system-wide monitoring case (instead of
sysconf) and uses cpumap[] to get the cpu numbers to pass to
perf_event_open.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
LKML-Reference: <20100310093609.GA3959@brick.ozlabs.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 6 changed files with 81 additions and 13 deletions Inline Diff

1 # The default target of this Makefile is... 1 # The default target of this Makefile is...
2 all:: 2 all::
3 3
4 # Define V=1 to have a more verbose compile. 4 # Define V=1 to have a more verbose compile.
5 # Define V=2 to have an even more verbose compile. 5 # Define V=2 to have an even more verbose compile.
6 # 6 #
7 # Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf() 7 # Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
8 # or vsnprintf() return -1 instead of number of characters which would 8 # or vsnprintf() return -1 instead of number of characters which would
9 # have been written to the final string if enough space had been available. 9 # have been written to the final string if enough space had been available.
10 # 10 #
11 # Define FREAD_READS_DIRECTORIES if your are on a system which succeeds 11 # Define FREAD_READS_DIRECTORIES if your are on a system which succeeds
12 # when attempting to read from an fopen'ed directory. 12 # when attempting to read from an fopen'ed directory.
13 # 13 #
14 # Define NO_OPENSSL environment variable if you do not have OpenSSL. 14 # Define NO_OPENSSL environment variable if you do not have OpenSSL.
15 # This also implies MOZILLA_SHA1. 15 # This also implies MOZILLA_SHA1.
16 # 16 #
17 # Define CURLDIR=/foo/bar if your curl header and library files are in 17 # Define CURLDIR=/foo/bar if your curl header and library files are in
18 # /foo/bar/include and /foo/bar/lib directories. 18 # /foo/bar/include and /foo/bar/lib directories.
19 # 19 #
20 # Define EXPATDIR=/foo/bar if your expat header and library files are in 20 # Define EXPATDIR=/foo/bar if your expat header and library files are in
21 # /foo/bar/include and /foo/bar/lib directories. 21 # /foo/bar/include and /foo/bar/lib directories.
22 # 22 #
23 # Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent. 23 # Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
24 # 24 #
25 # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks 25 # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
26 # d_type in struct dirent (latest Cygwin -- will be fixed soonish). 26 # d_type in struct dirent (latest Cygwin -- will be fixed soonish).
27 # 27 #
28 # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) 28 # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.)
29 # do not support the 'size specifiers' introduced by C99, namely ll, hh, 29 # do not support the 'size specifiers' introduced by C99, namely ll, hh,
30 # j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). 30 # j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t).
31 # some C compilers supported these specifiers prior to C99 as an extension. 31 # some C compilers supported these specifiers prior to C99 as an extension.
32 # 32 #
33 # Define NO_STRCASESTR if you don't have strcasestr. 33 # Define NO_STRCASESTR if you don't have strcasestr.
34 # 34 #
35 # Define NO_MEMMEM if you don't have memmem. 35 # Define NO_MEMMEM if you don't have memmem.
36 # 36 #
37 # Define NO_STRTOUMAX if you don't have strtoumax in the C library. 37 # Define NO_STRTOUMAX if you don't have strtoumax in the C library.
38 # If your compiler also does not support long long or does not have 38 # If your compiler also does not support long long or does not have
39 # strtoull, define NO_STRTOULL. 39 # strtoull, define NO_STRTOULL.
40 # 40 #
41 # Define NO_SETENV if you don't have setenv in the C library. 41 # Define NO_SETENV if you don't have setenv in the C library.
42 # 42 #
43 # Define NO_UNSETENV if you don't have unsetenv in the C library. 43 # Define NO_UNSETENV if you don't have unsetenv in the C library.
44 # 44 #
45 # Define NO_MKDTEMP if you don't have mkdtemp in the C library. 45 # Define NO_MKDTEMP if you don't have mkdtemp in the C library.
46 # 46 #
47 # Define NO_SYS_SELECT_H if you don't have sys/select.h. 47 # Define NO_SYS_SELECT_H if you don't have sys/select.h.
48 # 48 #
49 # Define NO_SYMLINK_HEAD if you never want .perf/HEAD to be a symbolic link. 49 # Define NO_SYMLINK_HEAD if you never want .perf/HEAD to be a symbolic link.
50 # Enable it on Windows. By default, symrefs are still used. 50 # Enable it on Windows. By default, symrefs are still used.
51 # 51 #
52 # Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability 52 # Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability
53 # tests. These tests take up a significant amount of the total test time 53 # tests. These tests take up a significant amount of the total test time
54 # but are not needed unless you plan to talk to SVN repos. 54 # but are not needed unless you plan to talk to SVN repos.
55 # 55 #
56 # Define NO_FINK if you are building on Darwin/Mac OS X, have Fink 56 # Define NO_FINK if you are building on Darwin/Mac OS X, have Fink
57 # installed in /sw, but don't want PERF to link against any libraries 57 # installed in /sw, but don't want PERF to link against any libraries
58 # installed there. If defined you may specify your own (or Fink's) 58 # installed there. If defined you may specify your own (or Fink's)
59 # include directories and library directories by defining CFLAGS 59 # include directories and library directories by defining CFLAGS
60 # and LDFLAGS appropriately. 60 # and LDFLAGS appropriately.
61 # 61 #
62 # Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X, 62 # Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X,
63 # have DarwinPorts installed in /opt/local, but don't want PERF to 63 # have DarwinPorts installed in /opt/local, but don't want PERF to
64 # link against any libraries installed there. If defined you may 64 # link against any libraries installed there. If defined you may
65 # specify your own (or DarwinPort's) include directories and 65 # specify your own (or DarwinPort's) include directories and
66 # library directories by defining CFLAGS and LDFLAGS appropriately. 66 # library directories by defining CFLAGS and LDFLAGS appropriately.
67 # 67 #
68 # Define PPC_SHA1 environment variable when running make to make use of 68 # Define PPC_SHA1 environment variable when running make to make use of
69 # a bundled SHA1 routine optimized for PowerPC. 69 # a bundled SHA1 routine optimized for PowerPC.
70 # 70 #
71 # Define ARM_SHA1 environment variable when running make to make use of 71 # Define ARM_SHA1 environment variable when running make to make use of
72 # a bundled SHA1 routine optimized for ARM. 72 # a bundled SHA1 routine optimized for ARM.
73 # 73 #
74 # Define MOZILLA_SHA1 environment variable when running make to make use of 74 # Define MOZILLA_SHA1 environment variable when running make to make use of
75 # a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast 75 # a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast
76 # on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default 76 # on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default
77 # choice) has very fast version optimized for i586. 77 # choice) has very fast version optimized for i586.
78 # 78 #
79 # Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin). 79 # Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin).
80 # 80 #
81 # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). 81 # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
82 # 82 #
83 # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, 83 # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
84 # Patrick Mauritz). 84 # Patrick Mauritz).
85 # 85 #
86 # Define NO_MMAP if you want to avoid mmap. 86 # Define NO_MMAP if you want to avoid mmap.
87 # 87 #
88 # Define NO_PTHREADS if you do not have or do not want to use Pthreads. 88 # Define NO_PTHREADS if you do not have or do not want to use Pthreads.
89 # 89 #
90 # Define NO_PREAD if you have a problem with pread() system call (e.g. 90 # Define NO_PREAD if you have a problem with pread() system call (e.g.
91 # cygwin.dll before v1.5.22). 91 # cygwin.dll before v1.5.22).
92 # 92 #
93 # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is 93 # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
94 # generally faster on your platform than accessing the working directory. 94 # generally faster on your platform than accessing the working directory.
95 # 95 #
96 # Define NO_TRUSTABLE_FILEMODE if your filesystem may claim to support 96 # Define NO_TRUSTABLE_FILEMODE if your filesystem may claim to support
97 # the executable mode bit, but doesn't really do so. 97 # the executable mode bit, but doesn't really do so.
98 # 98 #
99 # Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). 99 # Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
100 # 100 #
101 # Define NO_SOCKADDR_STORAGE if your platform does not have struct 101 # Define NO_SOCKADDR_STORAGE if your platform does not have struct
102 # sockaddr_storage. 102 # sockaddr_storage.
103 # 103 #
104 # Define NO_ICONV if your libc does not properly support iconv. 104 # Define NO_ICONV if your libc does not properly support iconv.
105 # 105 #
106 # Define OLD_ICONV if your library has an old iconv(), where the second 106 # Define OLD_ICONV if your library has an old iconv(), where the second
107 # (input buffer pointer) parameter is declared with type (const char **). 107 # (input buffer pointer) parameter is declared with type (const char **).
108 # 108 #
109 # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. 109 # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound.
110 # 110 #
111 # Define NO_R_TO_GCC_LINKER if your gcc does not like "-R/path/lib" 111 # Define NO_R_TO_GCC_LINKER if your gcc does not like "-R/path/lib"
112 # that tells runtime paths to dynamic libraries; 112 # that tells runtime paths to dynamic libraries;
113 # "-Wl,-rpath=/path/lib" is used instead. 113 # "-Wl,-rpath=/path/lib" is used instead.
114 # 114 #
115 # Define USE_NSEC below if you want perf to care about sub-second file mtimes 115 # Define USE_NSEC below if you want perf to care about sub-second file mtimes
116 # and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and 116 # and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
117 # it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely 117 # it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
118 # randomly break unless your underlying filesystem supports those sub-second 118 # randomly break unless your underlying filesystem supports those sub-second
119 # times (my ext3 doesn't). 119 # times (my ext3 doesn't).
120 # 120 #
121 # Define USE_ST_TIMESPEC if your "struct stat" uses "st_ctimespec" instead of 121 # Define USE_ST_TIMESPEC if your "struct stat" uses "st_ctimespec" instead of
122 # "st_ctim" 122 # "st_ctim"
123 # 123 #
124 # Define NO_NSEC if your "struct stat" does not have "st_ctim.tv_nsec" 124 # Define NO_NSEC if your "struct stat" does not have "st_ctim.tv_nsec"
125 # available. This automatically turns USE_NSEC off. 125 # available. This automatically turns USE_NSEC off.
126 # 126 #
127 # Define USE_STDEV below if you want perf to care about the underlying device 127 # Define USE_STDEV below if you want perf to care about the underlying device
128 # change being considered an inode change from the update-index perspective. 128 # change being considered an inode change from the update-index perspective.
129 # 129 #
130 # Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks 130 # Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks
131 # field that counts the on-disk footprint in 512-byte blocks. 131 # field that counts the on-disk footprint in 512-byte blocks.
132 # 132 #
133 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 133 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
134 # 134 #
135 # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72. 135 # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
136 # 136 #
137 # Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's 137 # Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
138 # MakeMaker (e.g. using ActiveState under Cygwin). 138 # MakeMaker (e.g. using ActiveState under Cygwin).
139 # 139 #
140 # Define NO_PERL if you do not want Perl scripts or libraries at all. 140 # Define NO_PERL if you do not want Perl scripts or libraries at all.
141 # 141 #
142 # Define INTERNAL_QSORT to use Git's implementation of qsort(), which 142 # Define INTERNAL_QSORT to use Git's implementation of qsort(), which
143 # is a simplified version of the merge sort used in glibc. This is 143 # is a simplified version of the merge sort used in glibc. This is
144 # recommended if Git triggers O(n^2) behavior in your platform's qsort(). 144 # recommended if Git triggers O(n^2) behavior in your platform's qsort().
145 # 145 #
146 # Define NO_EXTERNAL_GREP if you don't want "perf grep" to ever call 146 # Define NO_EXTERNAL_GREP if you don't want "perf grep" to ever call
147 # your external grep (e.g., if your system lacks grep, if its grep is 147 # your external grep (e.g., if your system lacks grep, if its grep is
148 # broken, or spawning external process is slower than built-in grep perf has). 148 # broken, or spawning external process is slower than built-in grep perf has).
149 # 149 #
150 # Define LDFLAGS=-static to build a static binary. 150 # Define LDFLAGS=-static to build a static binary.
151 # 151 #
152 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds. 152 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
153 153
154 PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE 154 PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
155 @$(SHELL_PATH) util/PERF-VERSION-GEN 155 @$(SHELL_PATH) util/PERF-VERSION-GEN
156 -include PERF-VERSION-FILE 156 -include PERF-VERSION-FILE
157 157
158 uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 158 uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
159 uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') 159 uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
160 uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') 160 uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
161 uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not') 161 uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
162 uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') 162 uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
163 uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') 163 uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
164 164
165 # CFLAGS and LDFLAGS are for the users to override from the command line. 165 # CFLAGS and LDFLAGS are for the users to override from the command line.
166 166
167 # 167 #
168 # Include saner warnings here, which can catch bugs: 168 # Include saner warnings here, which can catch bugs:
169 # 169 #
170 170
171 EXTRA_WARNINGS := -Wformat 171 EXTRA_WARNINGS := -Wformat
172 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security 172 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security
173 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k 173 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k
174 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow 174 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow
175 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Winit-self 175 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Winit-self
176 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wpacked 176 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wpacked
177 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wredundant-decls 177 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wredundant-decls
178 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstack-protector 178 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstack-protector
179 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-aliasing=3 179 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-aliasing=3
180 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-default 180 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-default
181 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-enum 181 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-enum
182 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wno-system-headers 182 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wno-system-headers
183 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wundef 183 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wundef
184 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wvolatile-register-var 184 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wvolatile-register-var
185 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wwrite-strings 185 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wwrite-strings
186 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wbad-function-cast 186 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wbad-function-cast
187 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-declarations 187 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-declarations
188 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-prototypes 188 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-prototypes
189 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wnested-externs 189 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wnested-externs
190 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition 190 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition
191 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes 191 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes
192 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement 192 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement
193 193
194 ifeq ("$(origin DEBUG)", "command line") 194 ifeq ("$(origin DEBUG)", "command line")
195 PERF_DEBUG = $(DEBUG) 195 PERF_DEBUG = $(DEBUG)
196 endif 196 endif
197 ifndef PERF_DEBUG 197 ifndef PERF_DEBUG
198 CFLAGS_OPTIMIZE = -O6 198 CFLAGS_OPTIMIZE = -O6
199 endif 199 endif
200 200
201 CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 201 CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
202 EXTLIBS = -lpthread -lrt -lelf -lm 202 EXTLIBS = -lpthread -lrt -lelf -lm
203 ALL_CFLAGS = $(CFLAGS) 203 ALL_CFLAGS = $(CFLAGS)
204 ALL_LDFLAGS = $(LDFLAGS) 204 ALL_LDFLAGS = $(LDFLAGS)
205 STRIP ?= strip 205 STRIP ?= strip
206 206
207 # Among the variables below, these: 207 # Among the variables below, these:
208 # perfexecdir 208 # perfexecdir
209 # template_dir 209 # template_dir
210 # mandir 210 # mandir
211 # infodir 211 # infodir
212 # htmldir 212 # htmldir
213 # ETC_PERFCONFIG (but not sysconfdir) 213 # ETC_PERFCONFIG (but not sysconfdir)
214 # can be specified as a relative path some/where/else; 214 # can be specified as a relative path some/where/else;
215 # this is interpreted as relative to $(prefix) and "perf" at 215 # this is interpreted as relative to $(prefix) and "perf" at
216 # runtime figures out where they are based on the path to the executable. 216 # runtime figures out where they are based on the path to the executable.
217 # This can help installing the suite in a relocatable way. 217 # This can help installing the suite in a relocatable way.
218 218
219 prefix = $(HOME) 219 prefix = $(HOME)
220 bindir_relative = bin 220 bindir_relative = bin
221 bindir = $(prefix)/$(bindir_relative) 221 bindir = $(prefix)/$(bindir_relative)
222 mandir = share/man 222 mandir = share/man
223 infodir = share/info 223 infodir = share/info
224 perfexecdir = libexec/perf-core 224 perfexecdir = libexec/perf-core
225 sharedir = $(prefix)/share 225 sharedir = $(prefix)/share
226 template_dir = share/perf-core/templates 226 template_dir = share/perf-core/templates
227 htmldir = share/doc/perf-doc 227 htmldir = share/doc/perf-doc
228 ifeq ($(prefix),/usr) 228 ifeq ($(prefix),/usr)
229 sysconfdir = /etc 229 sysconfdir = /etc
230 ETC_PERFCONFIG = $(sysconfdir)/perfconfig 230 ETC_PERFCONFIG = $(sysconfdir)/perfconfig
231 else 231 else
232 sysconfdir = $(prefix)/etc 232 sysconfdir = $(prefix)/etc
233 ETC_PERFCONFIG = etc/perfconfig 233 ETC_PERFCONFIG = etc/perfconfig
234 endif 234 endif
235 lib = lib 235 lib = lib
236 # DESTDIR= 236 # DESTDIR=
237 237
238 export prefix bindir sharedir sysconfdir 238 export prefix bindir sharedir sysconfdir
239 239
240 CC = $(CROSS_COMPILE)gcc 240 CC = $(CROSS_COMPILE)gcc
241 AR = $(CROSS_COMPILE)ar 241 AR = $(CROSS_COMPILE)ar
242 RM = rm -f 242 RM = rm -f
243 TAR = tar 243 TAR = tar
244 FIND = find 244 FIND = find
245 INSTALL = install 245 INSTALL = install
246 RPMBUILD = rpmbuild 246 RPMBUILD = rpmbuild
247 PTHREAD_LIBS = -lpthread 247 PTHREAD_LIBS = -lpthread
248 248
249 # sparse is architecture-neutral, which means that we need to tell it 249 # sparse is architecture-neutral, which means that we need to tell it
250 # explicitly what architecture to check for. Fix this up for yours.. 250 # explicitly what architecture to check for. Fix this up for yours..
251 SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ 251 SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
252 252
253 ifeq ($(V), 2) 253 ifeq ($(V), 2)
254 QUIET_STDERR = ">/dev/null" 254 QUIET_STDERR = ">/dev/null"
255 else 255 else
256 QUIET_STDERR = ">/dev/null 2>&1" 256 QUIET_STDERR = ">/dev/null 2>&1"
257 endif 257 endif
258 258
259 BITBUCKET = "/dev/null" 259 BITBUCKET = "/dev/null"
260 260
261 ifneq ($(shell sh -c "(echo '\#include <stdio.h>'; echo 'int main(void) { return puts(\"hi\"); }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y) 261 ifneq ($(shell sh -c "(echo '\#include <stdio.h>'; echo 'int main(void) { return puts(\"hi\"); }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y)
262 BITBUCKET = .perf.dev.null 262 BITBUCKET = .perf.dev.null
263 endif 263 endif
264 264
265 ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y) 265 ifeq ($(shell sh -c "echo 'int foo(void) {char X[2]; return 3;}' | $(CC) -x c -c -Werror -fstack-protector-all - -o $(BITBUCKET) "$(QUIET_STDERR)" && echo y"), y)
266 CFLAGS := $(CFLAGS) -fstack-protector-all 266 CFLAGS := $(CFLAGS) -fstack-protector-all
267 endif 267 endif
268 268
269 269
270 ### --- END CONFIGURATION SECTION --- 270 ### --- END CONFIGURATION SECTION ---
271 271
272 # Those must not be GNU-specific; they are shared with perl/ which may 272 # Those must not be GNU-specific; they are shared with perl/ which may
273 # be built by a different compiler. (Note that this is an artifact now 273 # be built by a different compiler. (Note that this is an artifact now
274 # but it still might be nice to keep that distinction.) 274 # but it still might be nice to keep that distinction.)
275 BASIC_CFLAGS = -Iutil/include 275 BASIC_CFLAGS = -Iutil/include
276 BASIC_LDFLAGS = 276 BASIC_LDFLAGS =
277 277
278 # Guard against environment variables 278 # Guard against environment variables
279 BUILTIN_OBJS = 279 BUILTIN_OBJS =
280 BUILT_INS = 280 BUILT_INS =
281 COMPAT_CFLAGS = 281 COMPAT_CFLAGS =
282 COMPAT_OBJS = 282 COMPAT_OBJS =
283 LIB_H = 283 LIB_H =
284 LIB_OBJS = 284 LIB_OBJS =
285 SCRIPT_PERL = 285 SCRIPT_PERL =
286 SCRIPT_SH = 286 SCRIPT_SH =
287 TEST_PROGRAMS = 287 TEST_PROGRAMS =
288 288
289 SCRIPT_SH += perf-archive.sh 289 SCRIPT_SH += perf-archive.sh
290 290
291 # 291 #
292 # No Perl scripts right now: 292 # No Perl scripts right now:
293 # 293 #
294 294
295 # SCRIPT_PERL += perf-add--interactive.perl 295 # SCRIPT_PERL += perf-add--interactive.perl
296 296
297 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ 297 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
298 $(patsubst %.perl,%,$(SCRIPT_PERL)) 298 $(patsubst %.perl,%,$(SCRIPT_PERL))
299 299
300 # Empty... 300 # Empty...
301 EXTRA_PROGRAMS = 301 EXTRA_PROGRAMS =
302 302
303 # ... and all the rest that could be moved out of bindir to perfexecdir 303 # ... and all the rest that could be moved out of bindir to perfexecdir
304 PROGRAMS += $(EXTRA_PROGRAMS) 304 PROGRAMS += $(EXTRA_PROGRAMS)
305 305
306 # 306 #
307 # Single 'perf' binary right now: 307 # Single 'perf' binary right now:
308 # 308 #
309 PROGRAMS += perf 309 PROGRAMS += perf
310 310
311 # List built-in command $C whose implementation cmd_$C() is not in 311 # List built-in command $C whose implementation cmd_$C() is not in
312 # builtin-$C.o but is linked in as part of some other command. 312 # builtin-$C.o but is linked in as part of some other command.
313 # 313 #
314 314
315 # what 'all' will build and 'install' will install, in perfexecdir 315 # what 'all' will build and 'install' will install, in perfexecdir
316 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) 316 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
317 317
318 # what 'all' will build but not install in perfexecdir 318 # what 'all' will build but not install in perfexecdir
319 OTHER_PROGRAMS = perf$X 319 OTHER_PROGRAMS = perf$X
320 320
321 # Set paths to tools early so that they can be used for version tests. 321 # Set paths to tools early so that they can be used for version tests.
322 ifndef SHELL_PATH 322 ifndef SHELL_PATH
323 SHELL_PATH = /bin/sh 323 SHELL_PATH = /bin/sh
324 endif 324 endif
325 ifndef PERL_PATH 325 ifndef PERL_PATH
326 PERL_PATH = /usr/bin/perl 326 PERL_PATH = /usr/bin/perl
327 endif 327 endif
328 328
329 export PERL_PATH 329 export PERL_PATH
330 330
331 LIB_FILE=libperf.a 331 LIB_FILE=libperf.a
332 332
333 LIB_H += ../../include/linux/perf_event.h 333 LIB_H += ../../include/linux/perf_event.h
334 LIB_H += ../../include/linux/rbtree.h 334 LIB_H += ../../include/linux/rbtree.h
335 LIB_H += ../../include/linux/list.h 335 LIB_H += ../../include/linux/list.h
336 LIB_H += ../../include/linux/hash.h 336 LIB_H += ../../include/linux/hash.h
337 LIB_H += ../../include/linux/stringify.h 337 LIB_H += ../../include/linux/stringify.h
338 LIB_H += util/include/linux/bitmap.h 338 LIB_H += util/include/linux/bitmap.h
339 LIB_H += util/include/linux/bitops.h 339 LIB_H += util/include/linux/bitops.h
340 LIB_H += util/include/linux/compiler.h 340 LIB_H += util/include/linux/compiler.h
341 LIB_H += util/include/linux/ctype.h 341 LIB_H += util/include/linux/ctype.h
342 LIB_H += util/include/linux/kernel.h 342 LIB_H += util/include/linux/kernel.h
343 LIB_H += util/include/linux/list.h 343 LIB_H += util/include/linux/list.h
344 LIB_H += util/include/linux/module.h 344 LIB_H += util/include/linux/module.h
345 LIB_H += util/include/linux/poison.h 345 LIB_H += util/include/linux/poison.h
346 LIB_H += util/include/linux/prefetch.h 346 LIB_H += util/include/linux/prefetch.h
347 LIB_H += util/include/linux/rbtree.h 347 LIB_H += util/include/linux/rbtree.h
348 LIB_H += util/include/linux/string.h 348 LIB_H += util/include/linux/string.h
349 LIB_H += util/include/linux/types.h 349 LIB_H += util/include/linux/types.h
350 LIB_H += util/include/asm/asm-offsets.h 350 LIB_H += util/include/asm/asm-offsets.h
351 LIB_H += util/include/asm/bitops.h 351 LIB_H += util/include/asm/bitops.h
352 LIB_H += util/include/asm/bug.h 352 LIB_H += util/include/asm/bug.h
353 LIB_H += util/include/asm/byteorder.h 353 LIB_H += util/include/asm/byteorder.h
354 LIB_H += util/include/asm/swab.h 354 LIB_H += util/include/asm/swab.h
355 LIB_H += util/include/asm/system.h 355 LIB_H += util/include/asm/system.h
356 LIB_H += util/include/asm/uaccess.h 356 LIB_H += util/include/asm/uaccess.h
357 LIB_H += perf.h 357 LIB_H += perf.h
358 LIB_H += util/cache.h 358 LIB_H += util/cache.h
359 LIB_H += util/callchain.h 359 LIB_H += util/callchain.h
360 LIB_H += util/build-id.h 360 LIB_H += util/build-id.h
361 LIB_H += util/debug.h 361 LIB_H += util/debug.h
362 LIB_H += util/debugfs.h 362 LIB_H += util/debugfs.h
363 LIB_H += util/event.h 363 LIB_H += util/event.h
364 LIB_H += util/exec_cmd.h 364 LIB_H += util/exec_cmd.h
365 LIB_H += util/types.h 365 LIB_H += util/types.h
366 LIB_H += util/levenshtein.h 366 LIB_H += util/levenshtein.h
367 LIB_H += util/map.h 367 LIB_H += util/map.h
368 LIB_H += util/parse-options.h 368 LIB_H += util/parse-options.h
369 LIB_H += util/parse-events.h 369 LIB_H += util/parse-events.h
370 LIB_H += util/quote.h 370 LIB_H += util/quote.h
371 LIB_H += util/util.h 371 LIB_H += util/util.h
372 LIB_H += util/header.h 372 LIB_H += util/header.h
373 LIB_H += util/help.h 373 LIB_H += util/help.h
374 LIB_H += util/session.h 374 LIB_H += util/session.h
375 LIB_H += util/strbuf.h 375 LIB_H += util/strbuf.h
376 LIB_H += util/string.h 376 LIB_H += util/string.h
377 LIB_H += util/strlist.h 377 LIB_H += util/strlist.h
378 LIB_H += util/svghelper.h 378 LIB_H += util/svghelper.h
379 LIB_H += util/run-command.h 379 LIB_H += util/run-command.h
380 LIB_H += util/sigchain.h 380 LIB_H += util/sigchain.h
381 LIB_H += util/symbol.h 381 LIB_H += util/symbol.h
382 LIB_H += util/color.h 382 LIB_H += util/color.h
383 LIB_H += util/values.h 383 LIB_H += util/values.h
384 LIB_H += util/sort.h 384 LIB_H += util/sort.h
385 LIB_H += util/hist.h 385 LIB_H += util/hist.h
386 LIB_H += util/thread.h 386 LIB_H += util/thread.h
387 LIB_H += util/trace-event.h 387 LIB_H += util/trace-event.h
388 LIB_H += util/probe-finder.h 388 LIB_H += util/probe-finder.h
389 LIB_H += util/probe-event.h 389 LIB_H += util/probe-event.h
390 LIB_H += util/cpumap.h
390 391
391 LIB_OBJS += util/abspath.o 392 LIB_OBJS += util/abspath.o
392 LIB_OBJS += util/alias.o 393 LIB_OBJS += util/alias.o
393 LIB_OBJS += util/build-id.o 394 LIB_OBJS += util/build-id.o
394 LIB_OBJS += util/config.o 395 LIB_OBJS += util/config.o
395 LIB_OBJS += util/ctype.o 396 LIB_OBJS += util/ctype.o
396 LIB_OBJS += util/debugfs.o 397 LIB_OBJS += util/debugfs.o
397 LIB_OBJS += util/environment.o 398 LIB_OBJS += util/environment.o
398 LIB_OBJS += util/event.o 399 LIB_OBJS += util/event.o
399 LIB_OBJS += util/exec_cmd.o 400 LIB_OBJS += util/exec_cmd.o
400 LIB_OBJS += util/help.o 401 LIB_OBJS += util/help.o
401 LIB_OBJS += util/levenshtein.o 402 LIB_OBJS += util/levenshtein.o
402 LIB_OBJS += util/parse-options.o 403 LIB_OBJS += util/parse-options.o
403 LIB_OBJS += util/parse-events.o 404 LIB_OBJS += util/parse-events.o
404 LIB_OBJS += util/path.o 405 LIB_OBJS += util/path.o
405 LIB_OBJS += util/rbtree.o 406 LIB_OBJS += util/rbtree.o
406 LIB_OBJS += util/bitmap.o 407 LIB_OBJS += util/bitmap.o
407 LIB_OBJS += util/hweight.o 408 LIB_OBJS += util/hweight.o
408 LIB_OBJS += util/find_next_bit.o 409 LIB_OBJS += util/find_next_bit.o
409 LIB_OBJS += util/run-command.o 410 LIB_OBJS += util/run-command.o
410 LIB_OBJS += util/quote.o 411 LIB_OBJS += util/quote.o
411 LIB_OBJS += util/strbuf.o 412 LIB_OBJS += util/strbuf.o
412 LIB_OBJS += util/string.o 413 LIB_OBJS += util/string.o
413 LIB_OBJS += util/strlist.o 414 LIB_OBJS += util/strlist.o
414 LIB_OBJS += util/usage.o 415 LIB_OBJS += util/usage.o
415 LIB_OBJS += util/wrapper.o 416 LIB_OBJS += util/wrapper.o
416 LIB_OBJS += util/sigchain.o 417 LIB_OBJS += util/sigchain.o
417 LIB_OBJS += util/symbol.o 418 LIB_OBJS += util/symbol.o
418 LIB_OBJS += util/color.o 419 LIB_OBJS += util/color.o
419 LIB_OBJS += util/pager.o 420 LIB_OBJS += util/pager.o
420 LIB_OBJS += util/header.o 421 LIB_OBJS += util/header.o
421 LIB_OBJS += util/callchain.o 422 LIB_OBJS += util/callchain.o
422 LIB_OBJS += util/values.o 423 LIB_OBJS += util/values.o
423 LIB_OBJS += util/debug.o 424 LIB_OBJS += util/debug.o
424 LIB_OBJS += util/map.o 425 LIB_OBJS += util/map.o
425 LIB_OBJS += util/session.o 426 LIB_OBJS += util/session.o
426 LIB_OBJS += util/thread.o 427 LIB_OBJS += util/thread.o
427 LIB_OBJS += util/trace-event-parse.o 428 LIB_OBJS += util/trace-event-parse.o
428 LIB_OBJS += util/trace-event-read.o 429 LIB_OBJS += util/trace-event-read.o
429 LIB_OBJS += util/trace-event-info.o 430 LIB_OBJS += util/trace-event-info.o
430 LIB_OBJS += util/trace-event-scripting.o 431 LIB_OBJS += util/trace-event-scripting.o
431 LIB_OBJS += util/svghelper.o 432 LIB_OBJS += util/svghelper.o
432 LIB_OBJS += util/sort.o 433 LIB_OBJS += util/sort.o
433 LIB_OBJS += util/hist.o 434 LIB_OBJS += util/hist.o
434 LIB_OBJS += util/probe-event.o 435 LIB_OBJS += util/probe-event.o
435 LIB_OBJS += util/util.o 436 LIB_OBJS += util/util.o
437 LIB_OBJS += util/cpumap.o
436 438
437 BUILTIN_OBJS += builtin-annotate.o 439 BUILTIN_OBJS += builtin-annotate.o
438 440
439 BUILTIN_OBJS += builtin-bench.o 441 BUILTIN_OBJS += builtin-bench.o
440 442
441 # Benchmark modules 443 # Benchmark modules
442 BUILTIN_OBJS += bench/sched-messaging.o 444 BUILTIN_OBJS += bench/sched-messaging.o
443 BUILTIN_OBJS += bench/sched-pipe.o 445 BUILTIN_OBJS += bench/sched-pipe.o
444 BUILTIN_OBJS += bench/mem-memcpy.o 446 BUILTIN_OBJS += bench/mem-memcpy.o
445 447
446 BUILTIN_OBJS += builtin-diff.o 448 BUILTIN_OBJS += builtin-diff.o
447 BUILTIN_OBJS += builtin-help.o 449 BUILTIN_OBJS += builtin-help.o
448 BUILTIN_OBJS += builtin-sched.o 450 BUILTIN_OBJS += builtin-sched.o
449 BUILTIN_OBJS += builtin-buildid-list.o 451 BUILTIN_OBJS += builtin-buildid-list.o
450 BUILTIN_OBJS += builtin-buildid-cache.o 452 BUILTIN_OBJS += builtin-buildid-cache.o
451 BUILTIN_OBJS += builtin-list.o 453 BUILTIN_OBJS += builtin-list.o
452 BUILTIN_OBJS += builtin-record.o 454 BUILTIN_OBJS += builtin-record.o
453 BUILTIN_OBJS += builtin-report.o 455 BUILTIN_OBJS += builtin-report.o
454 BUILTIN_OBJS += builtin-stat.o 456 BUILTIN_OBJS += builtin-stat.o
455 BUILTIN_OBJS += builtin-timechart.o 457 BUILTIN_OBJS += builtin-timechart.o
456 BUILTIN_OBJS += builtin-top.o 458 BUILTIN_OBJS += builtin-top.o
457 BUILTIN_OBJS += builtin-trace.o 459 BUILTIN_OBJS += builtin-trace.o
458 BUILTIN_OBJS += builtin-probe.o 460 BUILTIN_OBJS += builtin-probe.o
459 BUILTIN_OBJS += builtin-kmem.o 461 BUILTIN_OBJS += builtin-kmem.o
460 BUILTIN_OBJS += builtin-lock.o 462 BUILTIN_OBJS += builtin-lock.o
461 463
462 PERFLIBS = $(LIB_FILE) 464 PERFLIBS = $(LIB_FILE)
463 465
464 # 466 #
465 # Platform specific tweaks 467 # Platform specific tweaks
466 # 468 #
467 469
468 # We choose to avoid "if .. else if .. else .. endif endif" 470 # We choose to avoid "if .. else if .. else .. endif endif"
469 # because maintaining the nesting to match is a pain. If 471 # because maintaining the nesting to match is a pain. If
470 # we had "elif" things would have been much nicer... 472 # we had "elif" things would have been much nicer...
471 473
472 -include config.mak.autogen 474 -include config.mak.autogen
473 -include config.mak 475 -include config.mak
474 476
475 ifeq ($(uname_S),Darwin) 477 ifeq ($(uname_S),Darwin)
476 ifndef NO_FINK 478 ifndef NO_FINK
477 ifeq ($(shell test -d /sw/lib && echo y),y) 479 ifeq ($(shell test -d /sw/lib && echo y),y)
478 BASIC_CFLAGS += -I/sw/include 480 BASIC_CFLAGS += -I/sw/include
479 BASIC_LDFLAGS += -L/sw/lib 481 BASIC_LDFLAGS += -L/sw/lib
480 endif 482 endif
481 endif 483 endif
482 ifndef NO_DARWIN_PORTS 484 ifndef NO_DARWIN_PORTS
483 ifeq ($(shell test -d /opt/local/lib && echo y),y) 485 ifeq ($(shell test -d /opt/local/lib && echo y),y)
484 BASIC_CFLAGS += -I/opt/local/include 486 BASIC_CFLAGS += -I/opt/local/include
485 BASIC_LDFLAGS += -L/opt/local/lib 487 BASIC_LDFLAGS += -L/opt/local/lib
486 endif 488 endif
487 endif 489 endif
488 PTHREAD_LIBS = 490 PTHREAD_LIBS =
489 endif 491 endif
490 492
491 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) 493 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)
492 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) 494 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)
493 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); 495 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
494 endif 496 endif
495 497
496 ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 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) 498 ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 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)
497 BASIC_CFLAGS += -DLIBELF_NO_MMAP 499 BASIC_CFLAGS += -DLIBELF_NO_MMAP
498 endif 500 endif
499 else 501 else
500 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]); 502 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
501 endif 503 endif
502 504
503 ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) 505 ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
504 msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev); 506 msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
505 BASIC_CFLAGS += -DNO_DWARF_SUPPORT 507 BASIC_CFLAGS += -DNO_DWARF_SUPPORT
506 else 508 else
507 BASIC_CFLAGS += -I/usr/include/elfutils 509 BASIC_CFLAGS += -I/usr/include/elfutils
508 EXTLIBS += -lelf -ldw 510 EXTLIBS += -lelf -ldw
509 LIB_OBJS += util/probe-finder.o 511 LIB_OBJS += util/probe-finder.o
510 endif 512 endif
511 513
512 ifndef NO_LIBPERL 514 ifndef NO_LIBPERL
513 PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` 515 PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
514 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` 516 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
515 endif 517 endif
516 518
517 ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o $(BITBUCKET) $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y) 519 ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o $(BITBUCKET) $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
518 BASIC_CFLAGS += -DNO_LIBPERL 520 BASIC_CFLAGS += -DNO_LIBPERL
519 else 521 else
520 ALL_LDFLAGS += $(PERL_EMBED_LDOPTS) 522 ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
521 LIB_OBJS += util/scripting-engines/trace-event-perl.o 523 LIB_OBJS += util/scripting-engines/trace-event-perl.o
522 LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o 524 LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
523 endif 525 endif
524 526
525 ifndef NO_LIBPYTHON 527 ifndef NO_LIBPYTHON
526 PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null` 528 PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
527 PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` 529 PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
528 endif 530 endif
529 531
530 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) 532 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)
531 BASIC_CFLAGS += -DNO_LIBPYTHON 533 BASIC_CFLAGS += -DNO_LIBPYTHON
532 else 534 else
533 ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS) 535 ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
534 LIB_OBJS += util/scripting-engines/trace-event-python.o 536 LIB_OBJS += util/scripting-engines/trace-event-python.o
535 LIB_OBJS += scripts/python/Perf-Trace-Util/Context.o 537 LIB_OBJS += scripts/python/Perf-Trace-Util/Context.o
536 endif 538 endif
537 539
538 ifdef NO_DEMANGLE 540 ifdef NO_DEMANGLE
539 BASIC_CFLAGS += -DNO_DEMANGLE 541 BASIC_CFLAGS += -DNO_DEMANGLE
540 else 542 else
541 has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y") 543 has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y")
542 544
543 ifeq ($(has_bfd),y) 545 ifeq ($(has_bfd),y)
544 EXTLIBS += -lbfd 546 EXTLIBS += -lbfd
545 else 547 else
546 has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty "$(QUIET_STDERR)" && echo y") 548 has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty "$(QUIET_STDERR)" && echo y")
547 ifeq ($(has_bfd_iberty),y) 549 ifeq ($(has_bfd_iberty),y)
548 EXTLIBS += -lbfd -liberty 550 EXTLIBS += -lbfd -liberty
549 else 551 else
550 has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty -lz "$(QUIET_STDERR)" && echo y") 552 has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd -liberty -lz "$(QUIET_STDERR)" && echo y")
551 ifeq ($(has_bfd_iberty_z),y) 553 ifeq ($(has_bfd_iberty_z),y)
552 EXTLIBS += -lbfd -liberty -lz 554 EXTLIBS += -lbfd -liberty -lz
553 else 555 else
554 has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -liberty "$(QUIET_STDERR)" && echo y") 556 has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -liberty "$(QUIET_STDERR)" && echo y")
555 ifeq ($(has_cplus_demangle),y) 557 ifeq ($(has_cplus_demangle),y)
556 EXTLIBS += -liberty 558 EXTLIBS += -liberty
557 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE 559 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
558 else 560 else
559 msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling) 561 msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
560 BASIC_CFLAGS += -DNO_DEMANGLE 562 BASIC_CFLAGS += -DNO_DEMANGLE
561 endif 563 endif
562 endif 564 endif
563 endif 565 endif
564 endif 566 endif
565 endif 567 endif
566 568
567 ifndef CC_LD_DYNPATH 569 ifndef CC_LD_DYNPATH
568 ifdef NO_R_TO_GCC_LINKER 570 ifdef NO_R_TO_GCC_LINKER
569 # Some gcc does not accept and pass -R to the linker to specify 571 # Some gcc does not accept and pass -R to the linker to specify
570 # the runtime dynamic library path. 572 # the runtime dynamic library path.
571 CC_LD_DYNPATH = -Wl,-rpath, 573 CC_LD_DYNPATH = -Wl,-rpath,
572 else 574 else
573 CC_LD_DYNPATH = -R 575 CC_LD_DYNPATH = -R
574 endif 576 endif
575 endif 577 endif
576 578
577 ifdef NEEDS_SOCKET 579 ifdef NEEDS_SOCKET
578 EXTLIBS += -lsocket 580 EXTLIBS += -lsocket
579 endif 581 endif
580 ifdef NEEDS_NSL 582 ifdef NEEDS_NSL
581 EXTLIBS += -lnsl 583 EXTLIBS += -lnsl
582 endif 584 endif
583 ifdef NO_D_TYPE_IN_DIRENT 585 ifdef NO_D_TYPE_IN_DIRENT
584 BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT 586 BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT
585 endif 587 endif
586 ifdef NO_D_INO_IN_DIRENT 588 ifdef NO_D_INO_IN_DIRENT
587 BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT 589 BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT
588 endif 590 endif
589 ifdef NO_ST_BLOCKS_IN_STRUCT_STAT 591 ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
590 BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT 592 BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT
591 endif 593 endif
592 ifdef USE_NSEC 594 ifdef USE_NSEC
593 BASIC_CFLAGS += -DUSE_NSEC 595 BASIC_CFLAGS += -DUSE_NSEC
594 endif 596 endif
595 ifdef USE_ST_TIMESPEC 597 ifdef USE_ST_TIMESPEC
596 BASIC_CFLAGS += -DUSE_ST_TIMESPEC 598 BASIC_CFLAGS += -DUSE_ST_TIMESPEC
597 endif 599 endif
598 ifdef NO_NSEC 600 ifdef NO_NSEC
599 BASIC_CFLAGS += -DNO_NSEC 601 BASIC_CFLAGS += -DNO_NSEC
600 endif 602 endif
601 ifdef NO_C99_FORMAT 603 ifdef NO_C99_FORMAT
602 BASIC_CFLAGS += -DNO_C99_FORMAT 604 BASIC_CFLAGS += -DNO_C99_FORMAT
603 endif 605 endif
604 ifdef SNPRINTF_RETURNS_BOGUS 606 ifdef SNPRINTF_RETURNS_BOGUS
605 COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS 607 COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
606 COMPAT_OBJS += compat/snprintf.o 608 COMPAT_OBJS += compat/snprintf.o
607 endif 609 endif
608 ifdef FREAD_READS_DIRECTORIES 610 ifdef FREAD_READS_DIRECTORIES
609 COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES 611 COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
610 COMPAT_OBJS += compat/fopen.o 612 COMPAT_OBJS += compat/fopen.o
611 endif 613 endif
612 ifdef NO_SYMLINK_HEAD 614 ifdef NO_SYMLINK_HEAD
613 BASIC_CFLAGS += -DNO_SYMLINK_HEAD 615 BASIC_CFLAGS += -DNO_SYMLINK_HEAD
614 endif 616 endif
615 ifdef NO_STRCASESTR 617 ifdef NO_STRCASESTR
616 COMPAT_CFLAGS += -DNO_STRCASESTR 618 COMPAT_CFLAGS += -DNO_STRCASESTR
617 COMPAT_OBJS += compat/strcasestr.o 619 COMPAT_OBJS += compat/strcasestr.o
618 endif 620 endif
619 ifdef NO_STRTOUMAX 621 ifdef NO_STRTOUMAX
620 COMPAT_CFLAGS += -DNO_STRTOUMAX 622 COMPAT_CFLAGS += -DNO_STRTOUMAX
621 COMPAT_OBJS += compat/strtoumax.o 623 COMPAT_OBJS += compat/strtoumax.o
622 endif 624 endif
623 ifdef NO_STRTOULL 625 ifdef NO_STRTOULL
624 COMPAT_CFLAGS += -DNO_STRTOULL 626 COMPAT_CFLAGS += -DNO_STRTOULL
625 endif 627 endif
626 ifdef NO_SETENV 628 ifdef NO_SETENV
627 COMPAT_CFLAGS += -DNO_SETENV 629 COMPAT_CFLAGS += -DNO_SETENV
628 COMPAT_OBJS += compat/setenv.o 630 COMPAT_OBJS += compat/setenv.o
629 endif 631 endif
630 ifdef NO_MKDTEMP 632 ifdef NO_MKDTEMP
631 COMPAT_CFLAGS += -DNO_MKDTEMP 633 COMPAT_CFLAGS += -DNO_MKDTEMP
632 COMPAT_OBJS += compat/mkdtemp.o 634 COMPAT_OBJS += compat/mkdtemp.o
633 endif 635 endif
634 ifdef NO_UNSETENV 636 ifdef NO_UNSETENV
635 COMPAT_CFLAGS += -DNO_UNSETENV 637 COMPAT_CFLAGS += -DNO_UNSETENV
636 COMPAT_OBJS += compat/unsetenv.o 638 COMPAT_OBJS += compat/unsetenv.o
637 endif 639 endif
638 ifdef NO_SYS_SELECT_H 640 ifdef NO_SYS_SELECT_H
639 BASIC_CFLAGS += -DNO_SYS_SELECT_H 641 BASIC_CFLAGS += -DNO_SYS_SELECT_H
640 endif 642 endif
641 ifdef NO_MMAP 643 ifdef NO_MMAP
642 COMPAT_CFLAGS += -DNO_MMAP 644 COMPAT_CFLAGS += -DNO_MMAP
643 COMPAT_OBJS += compat/mmap.o 645 COMPAT_OBJS += compat/mmap.o
644 else 646 else
645 ifdef USE_WIN32_MMAP 647 ifdef USE_WIN32_MMAP
646 COMPAT_CFLAGS += -DUSE_WIN32_MMAP 648 COMPAT_CFLAGS += -DUSE_WIN32_MMAP
647 COMPAT_OBJS += compat/win32mmap.o 649 COMPAT_OBJS += compat/win32mmap.o
648 endif 650 endif
649 endif 651 endif
650 ifdef NO_PREAD 652 ifdef NO_PREAD
651 COMPAT_CFLAGS += -DNO_PREAD 653 COMPAT_CFLAGS += -DNO_PREAD
652 COMPAT_OBJS += compat/pread.o 654 COMPAT_OBJS += compat/pread.o
653 endif 655 endif
654 ifdef NO_FAST_WORKING_DIRECTORY 656 ifdef NO_FAST_WORKING_DIRECTORY
655 BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY 657 BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
656 endif 658 endif
657 ifdef NO_TRUSTABLE_FILEMODE 659 ifdef NO_TRUSTABLE_FILEMODE
658 BASIC_CFLAGS += -DNO_TRUSTABLE_FILEMODE 660 BASIC_CFLAGS += -DNO_TRUSTABLE_FILEMODE
659 endif 661 endif
660 ifdef NO_IPV6 662 ifdef NO_IPV6
661 BASIC_CFLAGS += -DNO_IPV6 663 BASIC_CFLAGS += -DNO_IPV6
662 endif 664 endif
663 ifdef NO_UINTMAX_T 665 ifdef NO_UINTMAX_T
664 BASIC_CFLAGS += -Duintmax_t=uint32_t 666 BASIC_CFLAGS += -Duintmax_t=uint32_t
665 endif 667 endif
666 ifdef NO_SOCKADDR_STORAGE 668 ifdef NO_SOCKADDR_STORAGE
667 ifdef NO_IPV6 669 ifdef NO_IPV6
668 BASIC_CFLAGS += -Dsockaddr_storage=sockaddr_in 670 BASIC_CFLAGS += -Dsockaddr_storage=sockaddr_in
669 else 671 else
670 BASIC_CFLAGS += -Dsockaddr_storage=sockaddr_in6 672 BASIC_CFLAGS += -Dsockaddr_storage=sockaddr_in6
671 endif 673 endif
672 endif 674 endif
673 ifdef NO_INET_NTOP 675 ifdef NO_INET_NTOP
674 LIB_OBJS += compat/inet_ntop.o 676 LIB_OBJS += compat/inet_ntop.o
675 endif 677 endif
676 ifdef NO_INET_PTON 678 ifdef NO_INET_PTON
677 LIB_OBJS += compat/inet_pton.o 679 LIB_OBJS += compat/inet_pton.o
678 endif 680 endif
679 681
680 ifdef NO_ICONV 682 ifdef NO_ICONV
681 BASIC_CFLAGS += -DNO_ICONV 683 BASIC_CFLAGS += -DNO_ICONV
682 endif 684 endif
683 685
684 ifdef OLD_ICONV 686 ifdef OLD_ICONV
685 BASIC_CFLAGS += -DOLD_ICONV 687 BASIC_CFLAGS += -DOLD_ICONV
686 endif 688 endif
687 689
688 ifdef NO_DEFLATE_BOUND 690 ifdef NO_DEFLATE_BOUND
689 BASIC_CFLAGS += -DNO_DEFLATE_BOUND 691 BASIC_CFLAGS += -DNO_DEFLATE_BOUND
690 endif 692 endif
691 693
692 ifdef PPC_SHA1 694 ifdef PPC_SHA1
693 SHA1_HEADER = "ppc/sha1.h" 695 SHA1_HEADER = "ppc/sha1.h"
694 LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o 696 LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
695 else 697 else
696 ifdef ARM_SHA1 698 ifdef ARM_SHA1
697 SHA1_HEADER = "arm/sha1.h" 699 SHA1_HEADER = "arm/sha1.h"
698 LIB_OBJS += arm/sha1.o arm/sha1_arm.o 700 LIB_OBJS += arm/sha1.o arm/sha1_arm.o
699 else 701 else
700 ifdef MOZILLA_SHA1 702 ifdef MOZILLA_SHA1
701 SHA1_HEADER = "mozilla-sha1/sha1.h" 703 SHA1_HEADER = "mozilla-sha1/sha1.h"
702 LIB_OBJS += mozilla-sha1/sha1.o 704 LIB_OBJS += mozilla-sha1/sha1.o
703 else 705 else
704 SHA1_HEADER = <openssl/sha.h> 706 SHA1_HEADER = <openssl/sha.h>
705 EXTLIBS += $(LIB_4_CRYPTO) 707 EXTLIBS += $(LIB_4_CRYPTO)
706 endif 708 endif
707 endif 709 endif
708 endif 710 endif
709 ifdef NO_PERL_MAKEMAKER 711 ifdef NO_PERL_MAKEMAKER
710 export NO_PERL_MAKEMAKER 712 export NO_PERL_MAKEMAKER
711 endif 713 endif
712 ifdef NO_HSTRERROR 714 ifdef NO_HSTRERROR
713 COMPAT_CFLAGS += -DNO_HSTRERROR 715 COMPAT_CFLAGS += -DNO_HSTRERROR
714 COMPAT_OBJS += compat/hstrerror.o 716 COMPAT_OBJS += compat/hstrerror.o
715 endif 717 endif
716 ifdef NO_MEMMEM 718 ifdef NO_MEMMEM
717 COMPAT_CFLAGS += -DNO_MEMMEM 719 COMPAT_CFLAGS += -DNO_MEMMEM
718 COMPAT_OBJS += compat/memmem.o 720 COMPAT_OBJS += compat/memmem.o
719 endif 721 endif
720 ifdef INTERNAL_QSORT 722 ifdef INTERNAL_QSORT
721 COMPAT_CFLAGS += -DINTERNAL_QSORT 723 COMPAT_CFLAGS += -DINTERNAL_QSORT
722 COMPAT_OBJS += compat/qsort.o 724 COMPAT_OBJS += compat/qsort.o
723 endif 725 endif
724 ifdef RUNTIME_PREFIX 726 ifdef RUNTIME_PREFIX
725 COMPAT_CFLAGS += -DRUNTIME_PREFIX 727 COMPAT_CFLAGS += -DRUNTIME_PREFIX
726 endif 728 endif
727 729
728 ifdef DIR_HAS_BSD_GROUP_SEMANTICS 730 ifdef DIR_HAS_BSD_GROUP_SEMANTICS
729 COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS 731 COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS
730 endif 732 endif
731 ifdef NO_EXTERNAL_GREP 733 ifdef NO_EXTERNAL_GREP
732 BASIC_CFLAGS += -DNO_EXTERNAL_GREP 734 BASIC_CFLAGS += -DNO_EXTERNAL_GREP
733 endif 735 endif
734 736
735 ifeq ($(PERL_PATH),) 737 ifeq ($(PERL_PATH),)
736 NO_PERL=NoThanks 738 NO_PERL=NoThanks
737 endif 739 endif
738 740
739 QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir 741 QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
740 QUIET_SUBDIR1 = 742 QUIET_SUBDIR1 =
741 743
742 ifneq ($(findstring $(MAKEFLAGS),w),w) 744 ifneq ($(findstring $(MAKEFLAGS),w),w)
743 PRINT_DIR = --no-print-directory 745 PRINT_DIR = --no-print-directory
744 else # "make -w" 746 else # "make -w"
745 NO_SUBDIR = : 747 NO_SUBDIR = :
746 endif 748 endif
747 749
748 ifneq ($(findstring $(MAKEFLAGS),s),s) 750 ifneq ($(findstring $(MAKEFLAGS),s),s)
749 ifndef V 751 ifndef V
750 QUIET_CC = @echo ' ' CC $@; 752 QUIET_CC = @echo ' ' CC $@;
751 QUIET_AR = @echo ' ' AR $@; 753 QUIET_AR = @echo ' ' AR $@;
752 QUIET_LINK = @echo ' ' LINK $@; 754 QUIET_LINK = @echo ' ' LINK $@;
753 QUIET_BUILT_IN = @echo ' ' BUILTIN $@; 755 QUIET_BUILT_IN = @echo ' ' BUILTIN $@;
754 QUIET_GEN = @echo ' ' GEN $@; 756 QUIET_GEN = @echo ' ' GEN $@;
755 QUIET_SUBDIR0 = +@subdir= 757 QUIET_SUBDIR0 = +@subdir=
756 QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ 758 QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
757 $(MAKE) $(PRINT_DIR) -C $$subdir 759 $(MAKE) $(PRINT_DIR) -C $$subdir
758 export V 760 export V
759 export QUIET_GEN 761 export QUIET_GEN
760 export QUIET_BUILT_IN 762 export QUIET_BUILT_IN
761 endif 763 endif
762 endif 764 endif
763 765
764 ifdef ASCIIDOC8 766 ifdef ASCIIDOC8
765 export ASCIIDOC8 767 export ASCIIDOC8
766 endif 768 endif
767 769
768 # Shell quote (do not use $(call) to accommodate ancient setups); 770 # Shell quote (do not use $(call) to accommodate ancient setups);
769 771
770 SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER)) 772 SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
771 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) 773 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
772 774
773 DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) 775 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
774 bindir_SQ = $(subst ','\'',$(bindir)) 776 bindir_SQ = $(subst ','\'',$(bindir))
775 bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) 777 bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
776 mandir_SQ = $(subst ','\'',$(mandir)) 778 mandir_SQ = $(subst ','\'',$(mandir))
777 infodir_SQ = $(subst ','\'',$(infodir)) 779 infodir_SQ = $(subst ','\'',$(infodir))
778 perfexecdir_SQ = $(subst ','\'',$(perfexecdir)) 780 perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
779 template_dir_SQ = $(subst ','\'',$(template_dir)) 781 template_dir_SQ = $(subst ','\'',$(template_dir))
780 htmldir_SQ = $(subst ','\'',$(htmldir)) 782 htmldir_SQ = $(subst ','\'',$(htmldir))
781 prefix_SQ = $(subst ','\'',$(prefix)) 783 prefix_SQ = $(subst ','\'',$(prefix))
782 784
783 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) 785 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
784 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) 786 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
785 787
786 LIBS = $(PERFLIBS) $(EXTLIBS) 788 LIBS = $(PERFLIBS) $(EXTLIBS)
787 789
788 BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \ 790 BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
789 $(COMPAT_CFLAGS) 791 $(COMPAT_CFLAGS)
790 LIB_OBJS += $(COMPAT_OBJS) 792 LIB_OBJS += $(COMPAT_OBJS)
791 793
792 ALL_CFLAGS += $(BASIC_CFLAGS) 794 ALL_CFLAGS += $(BASIC_CFLAGS)
793 ALL_LDFLAGS += $(BASIC_LDFLAGS) 795 ALL_LDFLAGS += $(BASIC_LDFLAGS)
794 796
795 export TAR INSTALL DESTDIR SHELL_PATH 797 export TAR INSTALL DESTDIR SHELL_PATH
796 798
797 799
798 ### Build rules 800 ### Build rules
799 801
800 SHELL = $(SHELL_PATH) 802 SHELL = $(SHELL_PATH)
801 803
802 all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS 804 all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS
803 ifneq (,$X) 805 ifneq (,$X)
804 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';) 806 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
805 endif 807 endif
806 808
807 all:: 809 all::
808 810
809 please_set_SHELL_PATH_to_a_more_modern_shell: 811 please_set_SHELL_PATH_to_a_more_modern_shell:
810 @$$(:) 812 @$$(:)
811 813
812 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell 814 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
813 815
814 strip: $(PROGRAMS) perf$X 816 strip: $(PROGRAMS) perf$X
815 $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X 817 $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X
816 818
817 perf.o: perf.c common-cmds.h PERF-CFLAGS 819 perf.o: perf.c common-cmds.h PERF-CFLAGS
818 $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \ 820 $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \
819 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 821 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
820 $(ALL_CFLAGS) -c $(filter %.c,$^) 822 $(ALL_CFLAGS) -c $(filter %.c,$^)
821 823
822 perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS) 824 perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS)
823 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \ 825 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \
824 $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) 826 $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
825 827
826 builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS 828 builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS
827 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ 829 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
828 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 830 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
829 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 831 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
830 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 832 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
831 833
832 builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS 834 builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS
833 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ 835 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
834 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 836 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
835 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 837 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
836 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 838 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
837 839
838 $(BUILT_INS): perf$X 840 $(BUILT_INS): perf$X
839 $(QUIET_BUILT_IN)$(RM) $@ && \ 841 $(QUIET_BUILT_IN)$(RM) $@ && \
840 ln perf$X $@ 2>/dev/null || \ 842 ln perf$X $@ 2>/dev/null || \
841 ln -s perf$X $@ 2>/dev/null || \ 843 ln -s perf$X $@ 2>/dev/null || \
842 cp perf$X $@ 844 cp perf$X $@
843 845
844 common-cmds.h: util/generate-cmdlist.sh command-list.txt 846 common-cmds.h: util/generate-cmdlist.sh command-list.txt
845 847
846 common-cmds.h: $(wildcard Documentation/perf-*.txt) 848 common-cmds.h: $(wildcard Documentation/perf-*.txt)
847 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ 849 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
848 850
849 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh 851 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
850 $(QUIET_GEN)$(RM) $@ $@+ && \ 852 $(QUIET_GEN)$(RM) $@ $@+ && \
851 sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ 853 sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
852 -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ 854 -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
853 -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ 855 -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
854 -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \ 856 -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \
855 -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ 857 -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
856 $@.sh >$@+ && \ 858 $@.sh >$@+ && \
857 chmod +x $@+ && \ 859 chmod +x $@+ && \
858 mv $@+ $@ 860 mv $@+ $@
859 861
860 configure: configure.ac 862 configure: configure.ac
861 $(QUIET_GEN)$(RM) $@ $<+ && \ 863 $(QUIET_GEN)$(RM) $@ $<+ && \
862 sed -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \ 864 sed -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \
863 $< > $<+ && \ 865 $< > $<+ && \
864 autoconf -o $@ $<+ && \ 866 autoconf -o $@ $<+ && \
865 $(RM) $<+ 867 $(RM) $<+
866 868
867 # These can record PERF_VERSION 869 # These can record PERF_VERSION
868 perf.o perf.spec \ 870 perf.o perf.spec \
869 $(patsubst %.sh,%,$(SCRIPT_SH)) \ 871 $(patsubst %.sh,%,$(SCRIPT_SH)) \
870 $(patsubst %.perl,%,$(SCRIPT_PERL)) \ 872 $(patsubst %.perl,%,$(SCRIPT_PERL)) \
871 : PERF-VERSION-FILE 873 : PERF-VERSION-FILE
872 874
873 %.o: %.c PERF-CFLAGS 875 %.o: %.c PERF-CFLAGS
874 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< 876 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
875 %.s: %.c PERF-CFLAGS 877 %.s: %.c PERF-CFLAGS
876 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< 878 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
877 %.o: %.S 879 %.o: %.S
878 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< 880 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
879 881
880 util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS 882 util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS
881 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ 883 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
882 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ 884 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
883 '-DBINDIR="$(bindir_relative_SQ)"' \ 885 '-DBINDIR="$(bindir_relative_SQ)"' \
884 '-DPREFIX="$(prefix_SQ)"' \ 886 '-DPREFIX="$(prefix_SQ)"' \
885 $< 887 $<
886 888
887 builtin-init-db.o: builtin-init-db.c PERF-CFLAGS 889 builtin-init-db.o: builtin-init-db.c PERF-CFLAGS
888 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $< 890 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
889 891
890 util/config.o: util/config.c PERF-CFLAGS 892 util/config.o: util/config.c PERF-CFLAGS
891 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 893 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
892 894
893 util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS 895 util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS
894 $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 896 $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
895 897
896 # some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing 898 # some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing
897 # from <string.h> that comes from kernel headers wrapping. 899 # from <string.h> that comes from kernel headers wrapping.
898 KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//` 900 KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//`
899 901
900 util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS 902 util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS
901 $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 903 $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
902 904
903 util/hweight.o: ../../lib/hweight.c PERF-CFLAGS 905 util/hweight.o: ../../lib/hweight.c PERF-CFLAGS
904 $(QUIET_CC)$(CC) -o util/hweight.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 906 $(QUIET_CC)$(CC) -o util/hweight.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
905 907
906 util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS 908 util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
907 $(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 909 $(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
908 910
909 util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c PERF-CFLAGS 911 util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c PERF-CFLAGS
910 $(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 $< 912 $(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 $<
911 913
912 scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS 914 scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS
913 $(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 $< 915 $(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 $<
914 916
915 util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c PERF-CFLAGS 917 util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c PERF-CFLAGS
916 $(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 $< 918 $(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 $<
917 919
918 scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c PERF-CFLAGS 920 scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c PERF-CFLAGS
919 $(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 $< 921 $(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 $<
920 922
921 perf-%$X: %.o $(PERFLIBS) 923 perf-%$X: %.o $(PERFLIBS)
922 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) 924 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
923 925
924 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) 926 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
925 $(patsubst perf-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) 927 $(patsubst perf-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
926 builtin-revert.o wt-status.o: wt-status.h 928 builtin-revert.o wt-status.o: wt-status.h
927 929
928 $(LIB_FILE): $(LIB_OBJS) 930 $(LIB_FILE): $(LIB_OBJS)
929 $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) 931 $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
930 932
931 doc: 933 doc:
932 $(MAKE) -C Documentation all 934 $(MAKE) -C Documentation all
933 935
934 man: 936 man:
935 $(MAKE) -C Documentation man 937 $(MAKE) -C Documentation man
936 938
937 html: 939 html:
938 $(MAKE) -C Documentation html 940 $(MAKE) -C Documentation html
939 941
940 info: 942 info:
941 $(MAKE) -C Documentation info 943 $(MAKE) -C Documentation info
942 944
943 pdf: 945 pdf:
944 $(MAKE) -C Documentation pdf 946 $(MAKE) -C Documentation pdf
945 947
946 TAGS: 948 TAGS:
947 $(RM) TAGS 949 $(RM) TAGS
948 $(FIND) . -name '*.[hcS]' -print | xargs etags -a 950 $(FIND) . -name '*.[hcS]' -print | xargs etags -a
949 951
950 tags: 952 tags:
951 $(RM) tags 953 $(RM) tags
952 $(FIND) . -name '*.[hcS]' -print | xargs ctags -a 954 $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
953 955
954 cscope: 956 cscope:
955 $(RM) cscope* 957 $(RM) cscope*
956 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b 958 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
957 959
958 ### Detect prefix changes 960 ### Detect prefix changes
959 TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ 961 TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
960 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) 962 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
961 963
962 PERF-CFLAGS: .FORCE-PERF-CFLAGS 964 PERF-CFLAGS: .FORCE-PERF-CFLAGS
963 @FLAGS='$(TRACK_CFLAGS)'; \ 965 @FLAGS='$(TRACK_CFLAGS)'; \
964 if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \ 966 if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \
965 echo 1>&2 " * new build flags or prefix"; \ 967 echo 1>&2 " * new build flags or prefix"; \
966 echo "$$FLAGS" >PERF-CFLAGS; \ 968 echo "$$FLAGS" >PERF-CFLAGS; \
967 fi 969 fi
968 970
969 # We need to apply sq twice, once to protect from the shell 971 # We need to apply sq twice, once to protect from the shell
970 # that runs PERF-BUILD-OPTIONS, and then again to protect it 972 # that runs PERF-BUILD-OPTIONS, and then again to protect it
971 # and the first level quoting from the shell that runs "echo". 973 # and the first level quoting from the shell that runs "echo".
972 PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS 974 PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
973 @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@ 975 @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
974 @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@ 976 @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
975 @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@ 977 @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
976 @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@ 978 @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@
977 979
978 ### Testing rules 980 ### Testing rules
979 981
980 # 982 #
981 # None right now: 983 # None right now:
982 # 984 #
983 # TEST_PROGRAMS += test-something$X 985 # TEST_PROGRAMS += test-something$X
984 986
985 all:: $(TEST_PROGRAMS) 987 all:: $(TEST_PROGRAMS)
986 988
987 # GNU make supports exporting all variables by "export" without parameters. 989 # GNU make supports exporting all variables by "export" without parameters.
988 # However, the environment gets quite big, and some programs have problems 990 # However, the environment gets quite big, and some programs have problems
989 # with that. 991 # with that.
990 992
991 export NO_SVN_TESTS 993 export NO_SVN_TESTS
992 994
993 check: common-cmds.h 995 check: common-cmds.h
994 if sparse; \ 996 if sparse; \
995 then \ 997 then \
996 for i in *.c */*.c; \ 998 for i in *.c */*.c; \
997 do \ 999 do \
998 sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \ 1000 sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
999 done; \ 1001 done; \
1000 else \ 1002 else \
1001 echo 2>&1 "Did you mean 'make test'?"; \ 1003 echo 2>&1 "Did you mean 'make test'?"; \
1002 exit 1; \ 1004 exit 1; \
1003 fi 1005 fi
1004 1006
1005 remove-dashes: 1007 remove-dashes:
1006 ./fixup-builtins $(BUILT_INS) $(PROGRAMS) $(SCRIPTS) 1008 ./fixup-builtins $(BUILT_INS) $(PROGRAMS) $(SCRIPTS)
1007 1009
1008 ### Installation rules 1010 ### Installation rules
1009 1011
1010 ifneq ($(filter /%,$(firstword $(template_dir))),) 1012 ifneq ($(filter /%,$(firstword $(template_dir))),)
1011 template_instdir = $(template_dir) 1013 template_instdir = $(template_dir)
1012 else 1014 else
1013 template_instdir = $(prefix)/$(template_dir) 1015 template_instdir = $(prefix)/$(template_dir)
1014 endif 1016 endif
1015 export template_instdir 1017 export template_instdir
1016 1018
1017 ifneq ($(filter /%,$(firstword $(perfexecdir))),) 1019 ifneq ($(filter /%,$(firstword $(perfexecdir))),)
1018 perfexec_instdir = $(perfexecdir) 1020 perfexec_instdir = $(perfexecdir)
1019 else 1021 else
1020 perfexec_instdir = $(prefix)/$(perfexecdir) 1022 perfexec_instdir = $(prefix)/$(perfexecdir)
1021 endif 1023 endif
1022 perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) 1024 perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
1023 export perfexec_instdir 1025 export perfexec_instdir
1024 1026
1025 install: all 1027 install: all
1026 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' 1028 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
1027 $(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)' 1029 $(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
1028 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 1030 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
1029 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 1031 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
1030 $(INSTALL) perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 1032 $(INSTALL) perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
1031 $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 1033 $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
1032 $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl' 1034 $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
1033 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 1035 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
1034 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace' 1036 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
1035 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' 1037 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
1036 $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace' 1038 $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
1037 $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python' 1039 $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'
1038 $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' 1040 $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
1039 1041
1040 ifdef BUILT_INS 1042 ifdef BUILT_INS
1041 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 1043 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
1042 $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 1044 $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
1043 ifneq (,$X) 1045 ifneq (,$X)
1044 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';) 1046 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
1045 endif 1047 endif
1046 endif 1048 endif
1047 1049
1048 install-doc: 1050 install-doc:
1049 $(MAKE) -C Documentation install 1051 $(MAKE) -C Documentation install
1050 1052
1051 install-man: 1053 install-man:
1052 $(MAKE) -C Documentation install-man 1054 $(MAKE) -C Documentation install-man
1053 1055
1054 install-html: 1056 install-html:
1055 $(MAKE) -C Documentation install-html 1057 $(MAKE) -C Documentation install-html
1056 1058
1057 install-info: 1059 install-info:
1058 $(MAKE) -C Documentation install-info 1060 $(MAKE) -C Documentation install-info
1059 1061
1060 install-pdf: 1062 install-pdf:
1061 $(MAKE) -C Documentation install-pdf 1063 $(MAKE) -C Documentation install-pdf
1062 1064
1063 quick-install-doc: 1065 quick-install-doc:
1064 $(MAKE) -C Documentation quick-install 1066 $(MAKE) -C Documentation quick-install
1065 1067
1066 quick-install-man: 1068 quick-install-man:
1067 $(MAKE) -C Documentation quick-install-man 1069 $(MAKE) -C Documentation quick-install-man
1068 1070
1069 quick-install-html: 1071 quick-install-html:
1070 $(MAKE) -C Documentation quick-install-html 1072 $(MAKE) -C Documentation quick-install-html
1071 1073
1072 1074
1073 ### Maintainer's dist rules 1075 ### Maintainer's dist rules
1074 # 1076 #
1075 # None right now 1077 # None right now
1076 # 1078 #
1077 # 1079 #
1078 # perf.spec: perf.spec.in 1080 # perf.spec: perf.spec.in
1079 # sed -e 's/@@VERSION@@/$(PERF_VERSION)/g' < $< > $@+ 1081 # sed -e 's/@@VERSION@@/$(PERF_VERSION)/g' < $< > $@+
1080 # mv $@+ $@ 1082 # mv $@+ $@
1081 # 1083 #
1082 # PERF_TARNAME=perf-$(PERF_VERSION) 1084 # PERF_TARNAME=perf-$(PERF_VERSION)
1083 # dist: perf.spec perf-archive$(X) configure 1085 # dist: perf.spec perf-archive$(X) configure
1084 # ./perf-archive --format=tar \ 1086 # ./perf-archive --format=tar \
1085 # --prefix=$(PERF_TARNAME)/ HEAD^{tree} > $(PERF_TARNAME).tar 1087 # --prefix=$(PERF_TARNAME)/ HEAD^{tree} > $(PERF_TARNAME).tar
1086 # @mkdir -p $(PERF_TARNAME) 1088 # @mkdir -p $(PERF_TARNAME)
1087 # @cp perf.spec configure $(PERF_TARNAME) 1089 # @cp perf.spec configure $(PERF_TARNAME)
1088 # @echo $(PERF_VERSION) > $(PERF_TARNAME)/version 1090 # @echo $(PERF_VERSION) > $(PERF_TARNAME)/version
1089 # $(TAR) rf $(PERF_TARNAME).tar \ 1091 # $(TAR) rf $(PERF_TARNAME).tar \
1090 # $(PERF_TARNAME)/perf.spec \ 1092 # $(PERF_TARNAME)/perf.spec \
1091 # $(PERF_TARNAME)/configure \ 1093 # $(PERF_TARNAME)/configure \
1092 # $(PERF_TARNAME)/version 1094 # $(PERF_TARNAME)/version
1093 # @$(RM) -r $(PERF_TARNAME) 1095 # @$(RM) -r $(PERF_TARNAME)
1094 # gzip -f -9 $(PERF_TARNAME).tar 1096 # gzip -f -9 $(PERF_TARNAME).tar
1095 # 1097 #
1096 # htmldocs = perf-htmldocs-$(PERF_VERSION) 1098 # htmldocs = perf-htmldocs-$(PERF_VERSION)
1097 # manpages = perf-manpages-$(PERF_VERSION) 1099 # manpages = perf-manpages-$(PERF_VERSION)
1098 # dist-doc: 1100 # dist-doc:
1099 # $(RM) -r .doc-tmp-dir 1101 # $(RM) -r .doc-tmp-dir
1100 # mkdir .doc-tmp-dir 1102 # mkdir .doc-tmp-dir
1101 # $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc 1103 # $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc
1102 # cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar . 1104 # cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar .
1103 # gzip -n -9 -f $(htmldocs).tar 1105 # gzip -n -9 -f $(htmldocs).tar
1104 # : 1106 # :
1105 # $(RM) -r .doc-tmp-dir 1107 # $(RM) -r .doc-tmp-dir
1106 # mkdir -p .doc-tmp-dir/man1 .doc-tmp-dir/man5 .doc-tmp-dir/man7 1108 # mkdir -p .doc-tmp-dir/man1 .doc-tmp-dir/man5 .doc-tmp-dir/man7
1107 # $(MAKE) -C Documentation DESTDIR=./ \ 1109 # $(MAKE) -C Documentation DESTDIR=./ \
1108 # man1dir=../.doc-tmp-dir/man1 \ 1110 # man1dir=../.doc-tmp-dir/man1 \
1109 # man5dir=../.doc-tmp-dir/man5 \ 1111 # man5dir=../.doc-tmp-dir/man5 \
1110 # man7dir=../.doc-tmp-dir/man7 \ 1112 # man7dir=../.doc-tmp-dir/man7 \
1111 # install 1113 # install
1112 # cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar . 1114 # cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
1113 # gzip -n -9 -f $(manpages).tar 1115 # gzip -n -9 -f $(manpages).tar
1114 # $(RM) -r .doc-tmp-dir 1116 # $(RM) -r .doc-tmp-dir
1115 # 1117 #
1116 # rpm: dist 1118 # rpm: dist
1117 # $(RPMBUILD) -ta $(PERF_TARNAME).tar.gz 1119 # $(RPMBUILD) -ta $(PERF_TARNAME).tar.gz
1118 1120
1119 ### Cleaning rules 1121 ### Cleaning rules
1120 1122
1121 distclean: clean 1123 distclean: clean
1122 # $(RM) configure 1124 # $(RM) configure
1123 1125
1124 clean: 1126 clean:
1125 $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE) 1127 $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
1126 $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X 1128 $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
1127 $(RM) $(TEST_PROGRAMS) 1129 $(RM) $(TEST_PROGRAMS)
1128 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope* 1130 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
1129 $(RM) -r autom4te.cache 1131 $(RM) -r autom4te.cache
1130 $(RM) config.log config.mak.autogen config.mak.append config.status config.cache 1132 $(RM) config.log config.mak.autogen config.mak.append config.status config.cache
1131 $(RM) -r $(PERF_TARNAME) .doc-tmp-dir 1133 $(RM) -r $(PERF_TARNAME) .doc-tmp-dir
1132 $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz 1134 $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz
1133 $(RM) $(htmldocs).tar.gz $(manpages).tar.gz 1135 $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
1134 $(MAKE) -C Documentation/ clean 1136 $(MAKE) -C Documentation/ clean
1135 $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS 1137 $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS
1136 1138
1137 .PHONY: all install clean strip 1139 .PHONY: all install clean strip
1138 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 1140 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
1139 .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS 1141 .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
1140 .PHONY: .FORCE-PERF-BUILD-OPTIONS 1142 .PHONY: .FORCE-PERF-BUILD-OPTIONS
1141 1143
1142 .perf.dev.null: 1144 .perf.dev.null:
1143 touch .perf.dev.null 1145 touch .perf.dev.null
1144 1146
1145 .INTERMEDIATE: .perf.dev.null 1147 .INTERMEDIATE: .perf.dev.null
1146 1148
1147 ### Make sure built-ins do not have dups and listed in perf.c 1149 ### Make sure built-ins do not have dups and listed in perf.c
1148 # 1150 #
1149 check-builtins:: 1151 check-builtins::
1150 ./check-builtins.sh 1152 ./check-builtins.sh
1151 1153
1152 ### Test suite coverage testing 1154 ### Test suite coverage testing
1153 # 1155 #
1154 # None right now 1156 # None right now
1155 # 1157 #
1156 # .PHONY: coverage coverage-clean coverage-build coverage-report 1158 # .PHONY: coverage coverage-clean coverage-build coverage-report
1157 # 1159 #
1158 # coverage: 1160 # coverage:
1159 # $(MAKE) coverage-build 1161 # $(MAKE) coverage-build
1160 # $(MAKE) coverage-report 1162 # $(MAKE) coverage-report
1161 # 1163 #
1162 # coverage-clean: 1164 # coverage-clean:
1163 # rm -f *.gcda *.gcno 1165 # rm -f *.gcda *.gcno
1164 # 1166 #
1165 # COVERAGE_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs 1167 # COVERAGE_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs
1166 # COVERAGE_LDFLAGS = $(CFLAGS) -O0 -lgcov 1168 # COVERAGE_LDFLAGS = $(CFLAGS) -O0 -lgcov
1167 # 1169 #
1168 # coverage-build: coverage-clean 1170 # coverage-build: coverage-clean
1169 # $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all 1171 # $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all
1170 # $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \ 1172 # $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
1171 # -j1 test 1173 # -j1 test
1172 # 1174 #
1173 # coverage-report: 1175 # coverage-report:
1174 # gcov -b *.c */*.c 1176 # gcov -b *.c */*.c
1175 # grep '^function.*called 0 ' *.c.gcov */*.c.gcov \ 1177 # grep '^function.*called 0 ' *.c.gcov */*.c.gcov \
1176 # | sed -e 's/\([^:]*\)\.gcov: *function \([^ ]*\) called.*/\1: \2/' \ 1178 # | sed -e 's/\([^:]*\)\.gcov: *function \([^ ]*\) called.*/\1: \2/' \
1177 # | tee coverage-untested-functions 1179 # | tee coverage-untested-functions
1178 1180
tools/perf/builtin-record.c
1 /* 1 /*
2 * builtin-record.c 2 * builtin-record.c
3 * 3 *
4 * Builtin record command: Record the profile of a workload 4 * Builtin record command: Record the profile of a workload
5 * (or a CPU, or a PID) into the perf.data output file - for 5 * (or a CPU, or a PID) into the perf.data output file - for
6 * later analysis via perf report. 6 * later analysis via perf report.
7 */ 7 */
8 #define _FILE_OFFSET_BITS 64 8 #define _FILE_OFFSET_BITS 64
9 9
10 #include "builtin.h" 10 #include "builtin.h"
11 11
12 #include "perf.h" 12 #include "perf.h"
13 13
14 #include "util/build-id.h" 14 #include "util/build-id.h"
15 #include "util/util.h" 15 #include "util/util.h"
16 #include "util/parse-options.h" 16 #include "util/parse-options.h"
17 #include "util/parse-events.h" 17 #include "util/parse-events.h"
18 #include "util/string.h" 18 #include "util/string.h"
19 19
20 #include "util/header.h" 20 #include "util/header.h"
21 #include "util/event.h" 21 #include "util/event.h"
22 #include "util/debug.h" 22 #include "util/debug.h"
23 #include "util/session.h" 23 #include "util/session.h"
24 #include "util/symbol.h" 24 #include "util/symbol.h"
25 #include "util/cpumap.h"
25 26
26 #include <unistd.h> 27 #include <unistd.h>
27 #include <sched.h> 28 #include <sched.h>
28 29
29 static int fd[MAX_NR_CPUS][MAX_COUNTERS]; 30 static int fd[MAX_NR_CPUS][MAX_COUNTERS];
30 31
31 static long default_interval = 0; 32 static long default_interval = 0;
32 33
33 static int nr_cpus = 0; 34 static int nr_cpus = 0;
34 static unsigned int page_size; 35 static unsigned int page_size;
35 static unsigned int mmap_pages = 128; 36 static unsigned int mmap_pages = 128;
36 static int freq = 1000; 37 static int freq = 1000;
37 static int output; 38 static int output;
38 static const char *output_name = "perf.data"; 39 static const char *output_name = "perf.data";
39 static int group = 0; 40 static int group = 0;
40 static unsigned int realtime_prio = 0; 41 static unsigned int realtime_prio = 0;
41 static int raw_samples = 0; 42 static int raw_samples = 0;
42 static int system_wide = 0; 43 static int system_wide = 0;
43 static int profile_cpu = -1; 44 static int profile_cpu = -1;
44 static pid_t target_pid = -1; 45 static pid_t target_pid = -1;
45 static pid_t child_pid = -1; 46 static pid_t child_pid = -1;
46 static int inherit = 1; 47 static int inherit = 1;
47 static int force = 0; 48 static int force = 0;
48 static int append_file = 0; 49 static int append_file = 0;
49 static int call_graph = 0; 50 static int call_graph = 0;
50 static int inherit_stat = 0; 51 static int inherit_stat = 0;
51 static int no_samples = 0; 52 static int no_samples = 0;
52 static int sample_address = 0; 53 static int sample_address = 0;
53 static int multiplex = 0; 54 static int multiplex = 0;
54 static int multiplex_fd = -1; 55 static int multiplex_fd = -1;
55 56
56 static long samples = 0; 57 static long samples = 0;
57 static struct timeval last_read; 58 static struct timeval last_read;
58 static struct timeval this_read; 59 static struct timeval this_read;
59 60
60 static u64 bytes_written = 0; 61 static u64 bytes_written = 0;
61 62
62 static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; 63 static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
63 64
64 static int nr_poll = 0; 65 static int nr_poll = 0;
65 static int nr_cpu = 0; 66 static int nr_cpu = 0;
66 67
67 static int file_new = 1; 68 static int file_new = 1;
68 static off_t post_processing_offset; 69 static off_t post_processing_offset;
69 70
70 static struct perf_session *session; 71 static struct perf_session *session;
71 72
72 struct mmap_data { 73 struct mmap_data {
73 int counter; 74 int counter;
74 void *base; 75 void *base;
75 unsigned int mask; 76 unsigned int mask;
76 unsigned int prev; 77 unsigned int prev;
77 }; 78 };
78 79
79 static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; 80 static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
80 81
81 static unsigned long mmap_read_head(struct mmap_data *md) 82 static unsigned long mmap_read_head(struct mmap_data *md)
82 { 83 {
83 struct perf_event_mmap_page *pc = md->base; 84 struct perf_event_mmap_page *pc = md->base;
84 long head; 85 long head;
85 86
86 head = pc->data_head; 87 head = pc->data_head;
87 rmb(); 88 rmb();
88 89
89 return head; 90 return head;
90 } 91 }
91 92
92 static void mmap_write_tail(struct mmap_data *md, unsigned long tail) 93 static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
93 { 94 {
94 struct perf_event_mmap_page *pc = md->base; 95 struct perf_event_mmap_page *pc = md->base;
95 96
96 /* 97 /*
97 * ensure all reads are done before we write the tail out. 98 * ensure all reads are done before we write the tail out.
98 */ 99 */
99 /* mb(); */ 100 /* mb(); */
100 pc->data_tail = tail; 101 pc->data_tail = tail;
101 } 102 }
102 103
103 static void write_output(void *buf, size_t size) 104 static void write_output(void *buf, size_t size)
104 { 105 {
105 while (size) { 106 while (size) {
106 int ret = write(output, buf, size); 107 int ret = write(output, buf, size);
107 108
108 if (ret < 0) 109 if (ret < 0)
109 die("failed to write"); 110 die("failed to write");
110 111
111 size -= ret; 112 size -= ret;
112 buf += ret; 113 buf += ret;
113 114
114 bytes_written += ret; 115 bytes_written += ret;
115 } 116 }
116 } 117 }
117 118
118 static int process_synthesized_event(event_t *event, 119 static int process_synthesized_event(event_t *event,
119 struct perf_session *self __used) 120 struct perf_session *self __used)
120 { 121 {
121 write_output(event, event->header.size); 122 write_output(event, event->header.size);
122 return 0; 123 return 0;
123 } 124 }
124 125
125 static void mmap_read(struct mmap_data *md) 126 static void mmap_read(struct mmap_data *md)
126 { 127 {
127 unsigned int head = mmap_read_head(md); 128 unsigned int head = mmap_read_head(md);
128 unsigned int old = md->prev; 129 unsigned int old = md->prev;
129 unsigned char *data = md->base + page_size; 130 unsigned char *data = md->base + page_size;
130 unsigned long size; 131 unsigned long size;
131 void *buf; 132 void *buf;
132 int diff; 133 int diff;
133 134
134 gettimeofday(&this_read, NULL); 135 gettimeofday(&this_read, NULL);
135 136
136 /* 137 /*
137 * If we're further behind than half the buffer, there's a chance 138 * If we're further behind than half the buffer, there's a chance
138 * the writer will bite our tail and mess up the samples under us. 139 * the writer will bite our tail and mess up the samples under us.
139 * 140 *
140 * If we somehow ended up ahead of the head, we got messed up. 141 * If we somehow ended up ahead of the head, we got messed up.
141 * 142 *
142 * In either case, truncate and restart at head. 143 * In either case, truncate and restart at head.
143 */ 144 */
144 diff = head - old; 145 diff = head - old;
145 if (diff < 0) { 146 if (diff < 0) {
146 struct timeval iv; 147 struct timeval iv;
147 unsigned long msecs; 148 unsigned long msecs;
148 149
149 timersub(&this_read, &last_read, &iv); 150 timersub(&this_read, &last_read, &iv);
150 msecs = iv.tv_sec*1000 + iv.tv_usec/1000; 151 msecs = iv.tv_sec*1000 + iv.tv_usec/1000;
151 152
152 fprintf(stderr, "WARNING: failed to keep up with mmap data." 153 fprintf(stderr, "WARNING: failed to keep up with mmap data."
153 " Last read %lu msecs ago.\n", msecs); 154 " Last read %lu msecs ago.\n", msecs);
154 155
155 /* 156 /*
156 * head points to a known good entry, start there. 157 * head points to a known good entry, start there.
157 */ 158 */
158 old = head; 159 old = head;
159 } 160 }
160 161
161 last_read = this_read; 162 last_read = this_read;
162 163
163 if (old != head) 164 if (old != head)
164 samples++; 165 samples++;
165 166
166 size = head - old; 167 size = head - old;
167 168
168 if ((old & md->mask) + size != (head & md->mask)) { 169 if ((old & md->mask) + size != (head & md->mask)) {
169 buf = &data[old & md->mask]; 170 buf = &data[old & md->mask];
170 size = md->mask + 1 - (old & md->mask); 171 size = md->mask + 1 - (old & md->mask);
171 old += size; 172 old += size;
172 173
173 write_output(buf, size); 174 write_output(buf, size);
174 } 175 }
175 176
176 buf = &data[old & md->mask]; 177 buf = &data[old & md->mask];
177 size = head - old; 178 size = head - old;
178 old += size; 179 old += size;
179 180
180 write_output(buf, size); 181 write_output(buf, size);
181 182
182 md->prev = old; 183 md->prev = old;
183 mmap_write_tail(md, old); 184 mmap_write_tail(md, old);
184 } 185 }
185 186
186 static volatile int done = 0; 187 static volatile int done = 0;
187 static volatile int signr = -1; 188 static volatile int signr = -1;
188 189
189 static void sig_handler(int sig) 190 static void sig_handler(int sig)
190 { 191 {
191 done = 1; 192 done = 1;
192 signr = sig; 193 signr = sig;
193 } 194 }
194 195
195 static void sig_atexit(void) 196 static void sig_atexit(void)
196 { 197 {
197 if (child_pid != -1) 198 if (child_pid != -1)
198 kill(child_pid, SIGTERM); 199 kill(child_pid, SIGTERM);
199 200
200 if (signr == -1) 201 if (signr == -1)
201 return; 202 return;
202 203
203 signal(signr, SIG_DFL); 204 signal(signr, SIG_DFL);
204 kill(getpid(), signr); 205 kill(getpid(), signr);
205 } 206 }
206 207
207 static int group_fd; 208 static int group_fd;
208 209
209 static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr) 210 static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
210 { 211 {
211 struct perf_header_attr *h_attr; 212 struct perf_header_attr *h_attr;
212 213
213 if (nr < session->header.attrs) { 214 if (nr < session->header.attrs) {
214 h_attr = session->header.attr[nr]; 215 h_attr = session->header.attr[nr];
215 } else { 216 } else {
216 h_attr = perf_header_attr__new(a); 217 h_attr = perf_header_attr__new(a);
217 if (h_attr != NULL) 218 if (h_attr != NULL)
218 if (perf_header__add_attr(&session->header, h_attr) < 0) { 219 if (perf_header__add_attr(&session->header, h_attr) < 0) {
219 perf_header_attr__delete(h_attr); 220 perf_header_attr__delete(h_attr);
220 h_attr = NULL; 221 h_attr = NULL;
221 } 222 }
222 } 223 }
223 224
224 return h_attr; 225 return h_attr;
225 } 226 }
226 227
227 static void create_counter(int counter, int cpu, pid_t pid) 228 static void create_counter(int counter, int cpu, pid_t pid)
228 { 229 {
229 char *filter = filters[counter]; 230 char *filter = filters[counter];
230 struct perf_event_attr *attr = attrs + counter; 231 struct perf_event_attr *attr = attrs + counter;
231 struct perf_header_attr *h_attr; 232 struct perf_header_attr *h_attr;
232 int track = !counter; /* only the first counter needs these */ 233 int track = !counter; /* only the first counter needs these */
233 int ret; 234 int ret;
234 struct { 235 struct {
235 u64 count; 236 u64 count;
236 u64 time_enabled; 237 u64 time_enabled;
237 u64 time_running; 238 u64 time_running;
238 u64 id; 239 u64 id;
239 } read_data; 240 } read_data;
240 241
241 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 242 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
242 PERF_FORMAT_TOTAL_TIME_RUNNING | 243 PERF_FORMAT_TOTAL_TIME_RUNNING |
243 PERF_FORMAT_ID; 244 PERF_FORMAT_ID;
244 245
245 attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; 246 attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
246 247
247 if (nr_counters > 1) 248 if (nr_counters > 1)
248 attr->sample_type |= PERF_SAMPLE_ID; 249 attr->sample_type |= PERF_SAMPLE_ID;
249 250
250 if (freq) { 251 if (freq) {
251 attr->sample_type |= PERF_SAMPLE_PERIOD; 252 attr->sample_type |= PERF_SAMPLE_PERIOD;
252 attr->freq = 1; 253 attr->freq = 1;
253 attr->sample_freq = freq; 254 attr->sample_freq = freq;
254 } 255 }
255 256
256 if (no_samples) 257 if (no_samples)
257 attr->sample_freq = 0; 258 attr->sample_freq = 0;
258 259
259 if (inherit_stat) 260 if (inherit_stat)
260 attr->inherit_stat = 1; 261 attr->inherit_stat = 1;
261 262
262 if (sample_address) 263 if (sample_address)
263 attr->sample_type |= PERF_SAMPLE_ADDR; 264 attr->sample_type |= PERF_SAMPLE_ADDR;
264 265
265 if (call_graph) 266 if (call_graph)
266 attr->sample_type |= PERF_SAMPLE_CALLCHAIN; 267 attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
267 268
268 if (raw_samples) { 269 if (raw_samples) {
269 attr->sample_type |= PERF_SAMPLE_TIME; 270 attr->sample_type |= PERF_SAMPLE_TIME;
270 attr->sample_type |= PERF_SAMPLE_RAW; 271 attr->sample_type |= PERF_SAMPLE_RAW;
271 attr->sample_type |= PERF_SAMPLE_CPU; 272 attr->sample_type |= PERF_SAMPLE_CPU;
272 } 273 }
273 274
274 attr->mmap = track; 275 attr->mmap = track;
275 attr->comm = track; 276 attr->comm = track;
276 attr->inherit = inherit; 277 attr->inherit = inherit;
277 attr->disabled = 1; 278 attr->disabled = 1;
278 279
279 try_again: 280 try_again:
280 fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0); 281 fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0);
281 282
282 if (fd[nr_cpu][counter] < 0) { 283 if (fd[nr_cpu][counter] < 0) {
283 int err = errno; 284 int err = errno;
284 285
285 if (err == EPERM || err == EACCES) 286 if (err == EPERM || err == EACCES)
286 die("Permission error - are you root?\n"); 287 die("Permission error - are you root?\n");
287 else if (err == ENODEV && profile_cpu != -1) 288 else if (err == ENODEV && profile_cpu != -1)
288 die("No such device - did you specify an out-of-range profile CPU?\n"); 289 die("No such device - did you specify an out-of-range profile CPU?\n");
289 290
290 /* 291 /*
291 * If it's cycles then fall back to hrtimer 292 * If it's cycles then fall back to hrtimer
292 * based cpu-clock-tick sw counter, which 293 * based cpu-clock-tick sw counter, which
293 * is always available even if no PMU support: 294 * is always available even if no PMU support:
294 */ 295 */
295 if (attr->type == PERF_TYPE_HARDWARE 296 if (attr->type == PERF_TYPE_HARDWARE
296 && attr->config == PERF_COUNT_HW_CPU_CYCLES) { 297 && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
297 298
298 if (verbose) 299 if (verbose)
299 warning(" ... trying to fall back to cpu-clock-ticks\n"); 300 warning(" ... trying to fall back to cpu-clock-ticks\n");
300 attr->type = PERF_TYPE_SOFTWARE; 301 attr->type = PERF_TYPE_SOFTWARE;
301 attr->config = PERF_COUNT_SW_CPU_CLOCK; 302 attr->config = PERF_COUNT_SW_CPU_CLOCK;
302 goto try_again; 303 goto try_again;
303 } 304 }
304 printf("\n"); 305 printf("\n");
305 error("perfcounter syscall returned with %d (%s)\n", 306 error("perfcounter syscall returned with %d (%s)\n",
306 fd[nr_cpu][counter], strerror(err)); 307 fd[nr_cpu][counter], strerror(err));
307 308
308 #if defined(__i386__) || defined(__x86_64__) 309 #if defined(__i386__) || defined(__x86_64__)
309 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP) 310 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
310 die("No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.\n"); 311 die("No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.\n");
311 #endif 312 #endif
312 313
313 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 314 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
314 exit(-1); 315 exit(-1);
315 } 316 }
316 317
317 h_attr = get_header_attr(attr, counter); 318 h_attr = get_header_attr(attr, counter);
318 if (h_attr == NULL) 319 if (h_attr == NULL)
319 die("nomem\n"); 320 die("nomem\n");
320 321
321 if (!file_new) { 322 if (!file_new) {
322 if (memcmp(&h_attr->attr, attr, sizeof(*attr))) { 323 if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
323 fprintf(stderr, "incompatible append\n"); 324 fprintf(stderr, "incompatible append\n");
324 exit(-1); 325 exit(-1);
325 } 326 }
326 } 327 }
327 328
328 if (read(fd[nr_cpu][counter], &read_data, sizeof(read_data)) == -1) { 329 if (read(fd[nr_cpu][counter], &read_data, sizeof(read_data)) == -1) {
329 perror("Unable to read perf file descriptor\n"); 330 perror("Unable to read perf file descriptor\n");
330 exit(-1); 331 exit(-1);
331 } 332 }
332 333
333 if (perf_header_attr__add_id(h_attr, read_data.id) < 0) { 334 if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
334 pr_warning("Not enough memory to add id\n"); 335 pr_warning("Not enough memory to add id\n");
335 exit(-1); 336 exit(-1);
336 } 337 }
337 338
338 assert(fd[nr_cpu][counter] >= 0); 339 assert(fd[nr_cpu][counter] >= 0);
339 fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK); 340 fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK);
340 341
341 /* 342 /*
342 * First counter acts as the group leader: 343 * First counter acts as the group leader:
343 */ 344 */
344 if (group && group_fd == -1) 345 if (group && group_fd == -1)
345 group_fd = fd[nr_cpu][counter]; 346 group_fd = fd[nr_cpu][counter];
346 if (multiplex && multiplex_fd == -1) 347 if (multiplex && multiplex_fd == -1)
347 multiplex_fd = fd[nr_cpu][counter]; 348 multiplex_fd = fd[nr_cpu][counter];
348 349
349 if (multiplex && fd[nr_cpu][counter] != multiplex_fd) { 350 if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
350 351
351 ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd); 352 ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
352 assert(ret != -1); 353 assert(ret != -1);
353 } else { 354 } else {
354 event_array[nr_poll].fd = fd[nr_cpu][counter]; 355 event_array[nr_poll].fd = fd[nr_cpu][counter];
355 event_array[nr_poll].events = POLLIN; 356 event_array[nr_poll].events = POLLIN;
356 nr_poll++; 357 nr_poll++;
357 358
358 mmap_array[nr_cpu][counter].counter = counter; 359 mmap_array[nr_cpu][counter].counter = counter;
359 mmap_array[nr_cpu][counter].prev = 0; 360 mmap_array[nr_cpu][counter].prev = 0;
360 mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1; 361 mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
361 mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size, 362 mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
362 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0); 363 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
363 if (mmap_array[nr_cpu][counter].base == MAP_FAILED) { 364 if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
364 error("failed to mmap with %d (%s)\n", errno, strerror(errno)); 365 error("failed to mmap with %d (%s)\n", errno, strerror(errno));
365 exit(-1); 366 exit(-1);
366 } 367 }
367 } 368 }
368 369
369 if (filter != NULL) { 370 if (filter != NULL) {
370 ret = ioctl(fd[nr_cpu][counter], 371 ret = ioctl(fd[nr_cpu][counter],
371 PERF_EVENT_IOC_SET_FILTER, filter); 372 PERF_EVENT_IOC_SET_FILTER, filter);
372 if (ret) { 373 if (ret) {
373 error("failed to set filter with %d (%s)\n", errno, 374 error("failed to set filter with %d (%s)\n", errno,
374 strerror(errno)); 375 strerror(errno));
375 exit(-1); 376 exit(-1);
376 } 377 }
377 } 378 }
378 379
379 ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE); 380 ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
380 } 381 }
381 382
382 static void open_counters(int cpu, pid_t pid) 383 static void open_counters(int cpu, pid_t pid)
383 { 384 {
384 int counter; 385 int counter;
385 386
386 group_fd = -1; 387 group_fd = -1;
387 for (counter = 0; counter < nr_counters; counter++) 388 for (counter = 0; counter < nr_counters; counter++)
388 create_counter(counter, cpu, pid); 389 create_counter(counter, cpu, pid);
389 390
390 nr_cpu++; 391 nr_cpu++;
391 } 392 }
392 393
393 static int process_buildids(void) 394 static int process_buildids(void)
394 { 395 {
395 u64 size = lseek(output, 0, SEEK_CUR); 396 u64 size = lseek(output, 0, SEEK_CUR);
396 397
397 session->fd = output; 398 session->fd = output;
398 return __perf_session__process_events(session, post_processing_offset, 399 return __perf_session__process_events(session, post_processing_offset,
399 size - post_processing_offset, 400 size - post_processing_offset,
400 size, &build_id__mark_dso_hit_ops); 401 size, &build_id__mark_dso_hit_ops);
401 } 402 }
402 403
403 static void atexit_header(void) 404 static void atexit_header(void)
404 { 405 {
405 session->header.data_size += bytes_written; 406 session->header.data_size += bytes_written;
406 407
407 process_buildids(); 408 process_buildids();
408 perf_header__write(&session->header, output, true); 409 perf_header__write(&session->header, output, true);
409 } 410 }
410 411
411 static int __cmd_record(int argc, const char **argv) 412 static int __cmd_record(int argc, const char **argv)
412 { 413 {
413 int i, counter; 414 int i, counter;
414 struct stat st; 415 struct stat st;
415 pid_t pid = 0; 416 pid_t pid = 0;
416 int flags; 417 int flags;
417 int err; 418 int err;
418 unsigned long waking = 0; 419 unsigned long waking = 0;
419 int child_ready_pipe[2], go_pipe[2]; 420 int child_ready_pipe[2], go_pipe[2];
420 const bool forks = target_pid == -1 && argc > 0; 421 const bool forks = target_pid == -1 && argc > 0;
421 char buf; 422 char buf;
422 423
423 page_size = sysconf(_SC_PAGE_SIZE); 424 page_size = sysconf(_SC_PAGE_SIZE);
424 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
425 assert(nr_cpus <= MAX_NR_CPUS);
426 assert(nr_cpus >= 0);
427 425
428 atexit(sig_atexit); 426 atexit(sig_atexit);
429 signal(SIGCHLD, sig_handler); 427 signal(SIGCHLD, sig_handler);
430 signal(SIGINT, sig_handler); 428 signal(SIGINT, sig_handler);
431 429
432 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { 430 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
433 perror("failed to create pipes"); 431 perror("failed to create pipes");
434 exit(-1); 432 exit(-1);
435 } 433 }
436 434
437 if (!stat(output_name, &st) && st.st_size) { 435 if (!stat(output_name, &st) && st.st_size) {
438 if (!force) { 436 if (!force) {
439 if (!append_file) { 437 if (!append_file) {
440 pr_err("Error, output file %s exists, use -A " 438 pr_err("Error, output file %s exists, use -A "
441 "to append or -f to overwrite.\n", 439 "to append or -f to overwrite.\n",
442 output_name); 440 output_name);
443 exit(-1); 441 exit(-1);
444 } 442 }
445 } else { 443 } else {
446 char oldname[PATH_MAX]; 444 char oldname[PATH_MAX];
447 snprintf(oldname, sizeof(oldname), "%s.old", 445 snprintf(oldname, sizeof(oldname), "%s.old",
448 output_name); 446 output_name);
449 unlink(oldname); 447 unlink(oldname);
450 rename(output_name, oldname); 448 rename(output_name, oldname);
451 } 449 }
452 } else { 450 } else {
453 append_file = 0; 451 append_file = 0;
454 } 452 }
455 453
456 flags = O_CREAT|O_RDWR; 454 flags = O_CREAT|O_RDWR;
457 if (append_file) 455 if (append_file)
458 file_new = 0; 456 file_new = 0;
459 else 457 else
460 flags |= O_TRUNC; 458 flags |= O_TRUNC;
461 459
462 output = open(output_name, flags, S_IRUSR|S_IWUSR); 460 output = open(output_name, flags, S_IRUSR|S_IWUSR);
463 if (output < 0) { 461 if (output < 0) {
464 perror("failed to create output file"); 462 perror("failed to create output file");
465 exit(-1); 463 exit(-1);
466 } 464 }
467 465
468 session = perf_session__new(output_name, O_WRONLY, force); 466 session = perf_session__new(output_name, O_WRONLY, force);
469 if (session == NULL) { 467 if (session == NULL) {
470 pr_err("Not enough memory for reading perf file header\n"); 468 pr_err("Not enough memory for reading perf file header\n");
471 return -1; 469 return -1;
472 } 470 }
473 471
474 if (!file_new) { 472 if (!file_new) {
475 err = perf_header__read(&session->header, output); 473 err = perf_header__read(&session->header, output);
476 if (err < 0) 474 if (err < 0)
477 return err; 475 return err;
478 } 476 }
479 477
480 if (raw_samples) { 478 if (raw_samples) {
481 perf_header__set_feat(&session->header, HEADER_TRACE_INFO); 479 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
482 } else { 480 } else {
483 for (i = 0; i < nr_counters; i++) { 481 for (i = 0; i < nr_counters; i++) {
484 if (attrs[i].sample_type & PERF_SAMPLE_RAW) { 482 if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
485 perf_header__set_feat(&session->header, HEADER_TRACE_INFO); 483 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
486 break; 484 break;
487 } 485 }
488 } 486 }
489 } 487 }
490 488
491 atexit(atexit_header); 489 atexit(atexit_header);
492 490
493 if (forks) { 491 if (forks) {
494 pid = fork(); 492 pid = fork();
495 if (pid < 0) { 493 if (pid < 0) {
496 perror("failed to fork"); 494 perror("failed to fork");
497 exit(-1); 495 exit(-1);
498 } 496 }
499 497
500 if (!pid) { 498 if (!pid) {
501 close(child_ready_pipe[0]); 499 close(child_ready_pipe[0]);
502 close(go_pipe[1]); 500 close(go_pipe[1]);
503 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 501 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
504 502
505 /* 503 /*
506 * Do a dummy execvp to get the PLT entry resolved, 504 * Do a dummy execvp to get the PLT entry resolved,
507 * so we avoid the resolver overhead on the real 505 * so we avoid the resolver overhead on the real
508 * execvp call. 506 * execvp call.
509 */ 507 */
510 execvp("", (char **)argv); 508 execvp("", (char **)argv);
511 509
512 /* 510 /*
513 * Tell the parent we're ready to go 511 * Tell the parent we're ready to go
514 */ 512 */
515 close(child_ready_pipe[1]); 513 close(child_ready_pipe[1]);
516 514
517 /* 515 /*
518 * Wait until the parent tells us to go. 516 * Wait until the parent tells us to go.
519 */ 517 */
520 if (read(go_pipe[0], &buf, 1) == -1) 518 if (read(go_pipe[0], &buf, 1) == -1)
521 perror("unable to read pipe"); 519 perror("unable to read pipe");
522 520
523 execvp(argv[0], (char **)argv); 521 execvp(argv[0], (char **)argv);
524 522
525 perror(argv[0]); 523 perror(argv[0]);
526 exit(-1); 524 exit(-1);
527 } 525 }
528 526
529 child_pid = pid; 527 child_pid = pid;
530 528
531 if (!system_wide) 529 if (!system_wide)
532 target_pid = pid; 530 target_pid = pid;
533 531
534 close(child_ready_pipe[1]); 532 close(child_ready_pipe[1]);
535 close(go_pipe[0]); 533 close(go_pipe[0]);
536 /* 534 /*
537 * wait for child to settle 535 * wait for child to settle
538 */ 536 */
539 if (read(child_ready_pipe[0], &buf, 1) == -1) { 537 if (read(child_ready_pipe[0], &buf, 1) == -1) {
540 perror("unable to read pipe"); 538 perror("unable to read pipe");
541 exit(-1); 539 exit(-1);
542 } 540 }
543 close(child_ready_pipe[0]); 541 close(child_ready_pipe[0]);
544 } 542 }
545 543
546 544
547 if ((!system_wide && !inherit) || profile_cpu != -1) { 545 if ((!system_wide && !inherit) || profile_cpu != -1) {
548 open_counters(profile_cpu, target_pid); 546 open_counters(profile_cpu, target_pid);
549 } else { 547 } else {
548 nr_cpus = read_cpu_map();
550 for (i = 0; i < nr_cpus; i++) 549 for (i = 0; i < nr_cpus; i++)
551 open_counters(i, target_pid); 550 open_counters(cpumap[i], target_pid);
552 } 551 }
553 552
554 if (file_new) { 553 if (file_new) {
555 err = perf_header__write(&session->header, output, false); 554 err = perf_header__write(&session->header, output, false);
556 if (err < 0) 555 if (err < 0)
557 return err; 556 return err;
558 } 557 }
559 558
560 post_processing_offset = lseek(output, 0, SEEK_CUR); 559 post_processing_offset = lseek(output, 0, SEEK_CUR);
561 560
562 err = event__synthesize_kernel_mmap(process_synthesized_event, 561 err = event__synthesize_kernel_mmap(process_synthesized_event,
563 session, "_text"); 562 session, "_text");
564 if (err < 0) { 563 if (err < 0) {
565 pr_err("Couldn't record kernel reference relocation symbol.\n"); 564 pr_err("Couldn't record kernel reference relocation symbol.\n");
566 return err; 565 return err;
567 } 566 }
568 567
569 err = event__synthesize_modules(process_synthesized_event, session); 568 err = event__synthesize_modules(process_synthesized_event, session);
570 if (err < 0) { 569 if (err < 0) {
571 pr_err("Couldn't record kernel reference relocation symbol.\n"); 570 pr_err("Couldn't record kernel reference relocation symbol.\n");
572 return err; 571 return err;
573 } 572 }
574 573
575 if (!system_wide && profile_cpu == -1) 574 if (!system_wide && profile_cpu == -1)
576 event__synthesize_thread(target_pid, process_synthesized_event, 575 event__synthesize_thread(target_pid, process_synthesized_event,
577 session); 576 session);
578 else 577 else
579 event__synthesize_threads(process_synthesized_event, session); 578 event__synthesize_threads(process_synthesized_event, session);
580 579
581 if (realtime_prio) { 580 if (realtime_prio) {
582 struct sched_param param; 581 struct sched_param param;
583 582
584 param.sched_priority = realtime_prio; 583 param.sched_priority = realtime_prio;
585 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 584 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
586 pr_err("Could not set realtime priority.\n"); 585 pr_err("Could not set realtime priority.\n");
587 exit(-1); 586 exit(-1);
588 } 587 }
589 } 588 }
590 589
591 /* 590 /*
592 * Let the child rip 591 * Let the child rip
593 */ 592 */
594 if (forks) 593 if (forks)
595 close(go_pipe[1]); 594 close(go_pipe[1]);
596 595
597 for (;;) { 596 for (;;) {
598 int hits = samples; 597 int hits = samples;
599 598
600 for (i = 0; i < nr_cpu; i++) { 599 for (i = 0; i < nr_cpu; i++) {
601 for (counter = 0; counter < nr_counters; counter++) { 600 for (counter = 0; counter < nr_counters; counter++) {
602 if (mmap_array[i][counter].base) 601 if (mmap_array[i][counter].base)
603 mmap_read(&mmap_array[i][counter]); 602 mmap_read(&mmap_array[i][counter]);
604 } 603 }
605 } 604 }
606 605
607 if (hits == samples) { 606 if (hits == samples) {
608 if (done) 607 if (done)
609 break; 608 break;
610 err = poll(event_array, nr_poll, -1); 609 err = poll(event_array, nr_poll, -1);
611 waking++; 610 waking++;
612 } 611 }
613 612
614 if (done) { 613 if (done) {
615 for (i = 0; i < nr_cpu; i++) { 614 for (i = 0; i < nr_cpu; i++) {
616 for (counter = 0; counter < nr_counters; counter++) 615 for (counter = 0; counter < nr_counters; counter++)
617 ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE); 616 ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE);
618 } 617 }
619 } 618 }
620 } 619 }
621 620
622 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 621 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
623 622
624 /* 623 /*
625 * Approximate RIP event size: 24 bytes. 624 * Approximate RIP event size: 24 bytes.
626 */ 625 */
627 fprintf(stderr, 626 fprintf(stderr,
628 "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n", 627 "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n",
629 (double)bytes_written / 1024.0 / 1024.0, 628 (double)bytes_written / 1024.0 / 1024.0,
630 output_name, 629 output_name,
631 bytes_written / 24); 630 bytes_written / 24);
632 631
633 return 0; 632 return 0;
634 } 633 }
635 634
636 static const char * const record_usage[] = { 635 static const char * const record_usage[] = {
637 "perf record [<options>] [<command>]", 636 "perf record [<options>] [<command>]",
638 "perf record [<options>] -- <command> [<options>]", 637 "perf record [<options>] -- <command> [<options>]",
639 NULL 638 NULL
640 }; 639 };
641 640
642 static const struct option options[] = { 641 static const struct option options[] = {
643 OPT_CALLBACK('e', "event", NULL, "event", 642 OPT_CALLBACK('e', "event", NULL, "event",
644 "event selector. use 'perf list' to list available events", 643 "event selector. use 'perf list' to list available events",
645 parse_events), 644 parse_events),
646 OPT_CALLBACK(0, "filter", NULL, "filter", 645 OPT_CALLBACK(0, "filter", NULL, "filter",
647 "event filter", parse_filter), 646 "event filter", parse_filter),
648 OPT_INTEGER('p', "pid", &target_pid, 647 OPT_INTEGER('p', "pid", &target_pid,
649 "record events on existing pid"), 648 "record events on existing pid"),
650 OPT_INTEGER('r', "realtime", &realtime_prio, 649 OPT_INTEGER('r', "realtime", &realtime_prio,
651 "collect data with this RT SCHED_FIFO priority"), 650 "collect data with this RT SCHED_FIFO priority"),
652 OPT_BOOLEAN('R', "raw-samples", &raw_samples, 651 OPT_BOOLEAN('R', "raw-samples", &raw_samples,
653 "collect raw sample records from all opened counters"), 652 "collect raw sample records from all opened counters"),
654 OPT_BOOLEAN('a', "all-cpus", &system_wide, 653 OPT_BOOLEAN('a', "all-cpus", &system_wide,
655 "system-wide collection from all CPUs"), 654 "system-wide collection from all CPUs"),
656 OPT_BOOLEAN('A', "append", &append_file, 655 OPT_BOOLEAN('A', "append", &append_file,
657 "append to the output file to do incremental profiling"), 656 "append to the output file to do incremental profiling"),
658 OPT_INTEGER('C', "profile_cpu", &profile_cpu, 657 OPT_INTEGER('C', "profile_cpu", &profile_cpu,
659 "CPU to profile on"), 658 "CPU to profile on"),
660 OPT_BOOLEAN('f', "force", &force, 659 OPT_BOOLEAN('f', "force", &force,
661 "overwrite existing data file"), 660 "overwrite existing data file"),
662 OPT_LONG('c', "count", &default_interval, 661 OPT_LONG('c', "count", &default_interval,
663 "event period to sample"), 662 "event period to sample"),
664 OPT_STRING('o', "output", &output_name, "file", 663 OPT_STRING('o', "output", &output_name, "file",
665 "output file name"), 664 "output file name"),
666 OPT_BOOLEAN('i', "inherit", &inherit, 665 OPT_BOOLEAN('i', "inherit", &inherit,
667 "child tasks inherit counters"), 666 "child tasks inherit counters"),
668 OPT_INTEGER('F', "freq", &freq, 667 OPT_INTEGER('F', "freq", &freq,
669 "profile at this frequency"), 668 "profile at this frequency"),
670 OPT_INTEGER('m', "mmap-pages", &mmap_pages, 669 OPT_INTEGER('m', "mmap-pages", &mmap_pages,
671 "number of mmap data pages"), 670 "number of mmap data pages"),
672 OPT_BOOLEAN('g', "call-graph", &call_graph, 671 OPT_BOOLEAN('g', "call-graph", &call_graph,
673 "do call-graph (stack chain/backtrace) recording"), 672 "do call-graph (stack chain/backtrace) recording"),
674 OPT_BOOLEAN('v', "verbose", &verbose, 673 OPT_BOOLEAN('v', "verbose", &verbose,
675 "be more verbose (show counter open errors, etc)"), 674 "be more verbose (show counter open errors, etc)"),
676 OPT_BOOLEAN('s', "stat", &inherit_stat, 675 OPT_BOOLEAN('s', "stat", &inherit_stat,
677 "per thread counts"), 676 "per thread counts"),
678 OPT_BOOLEAN('d', "data", &sample_address, 677 OPT_BOOLEAN('d', "data", &sample_address,
679 "Sample addresses"), 678 "Sample addresses"),
680 OPT_BOOLEAN('n', "no-samples", &no_samples, 679 OPT_BOOLEAN('n', "no-samples", &no_samples,
681 "don't sample"), 680 "don't sample"),
682 OPT_BOOLEAN('M', "multiplex", &multiplex, 681 OPT_BOOLEAN('M', "multiplex", &multiplex,
683 "multiplex counter output in a single channel"), 682 "multiplex counter output in a single channel"),
684 OPT_END() 683 OPT_END()
685 }; 684 };
686 685
687 int cmd_record(int argc, const char **argv, const char *prefix __used) 686 int cmd_record(int argc, const char **argv, const char *prefix __used)
688 { 687 {
689 int counter; 688 int counter;
690 689
691 argc = parse_options(argc, argv, options, record_usage, 690 argc = parse_options(argc, argv, options, record_usage,
692 PARSE_OPT_STOP_AT_NON_OPTION); 691 PARSE_OPT_STOP_AT_NON_OPTION);
693 if (!argc && target_pid == -1 && !system_wide && profile_cpu == -1) 692 if (!argc && target_pid == -1 && !system_wide && profile_cpu == -1)
694 usage_with_options(record_usage, options); 693 usage_with_options(record_usage, options);
695 694
696 symbol__init(); 695 symbol__init();
697 696
698 if (!nr_counters) { 697 if (!nr_counters) {
699 nr_counters = 1; 698 nr_counters = 1;
700 attrs[0].type = PERF_TYPE_HARDWARE; 699 attrs[0].type = PERF_TYPE_HARDWARE;
701 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES; 700 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
702 } 701 }
703 702
704 /* 703 /*
705 * User specified count overrides default frequency. 704 * User specified count overrides default frequency.
706 */ 705 */
707 if (default_interval) 706 if (default_interval)
708 freq = 0; 707 freq = 0;
709 else if (freq) { 708 else if (freq) {
710 default_interval = freq; 709 default_interval = freq;
711 } else { 710 } else {
712 fprintf(stderr, "frequency and count are zero, aborting\n"); 711 fprintf(stderr, "frequency and count are zero, aborting\n");
713 exit(EXIT_FAILURE); 712 exit(EXIT_FAILURE);
714 } 713 }
715 714
716 for (counter = 0; counter < nr_counters; counter++) { 715 for (counter = 0; counter < nr_counters; counter++) {
717 if (attrs[counter].sample_period) 716 if (attrs[counter].sample_period)
718 continue; 717 continue;
719 718
720 attrs[counter].sample_period = default_interval; 719 attrs[counter].sample_period = default_interval;
721 } 720 }
722 721
723 return __cmd_record(argc, argv); 722 return __cmd_record(argc, argv);
tools/perf/builtin-stat.c
1 /* 1 /*
2 * builtin-stat.c 2 * builtin-stat.c
3 * 3 *
4 * Builtin stat command: Give a precise performance counters summary 4 * Builtin stat command: Give a precise performance counters summary
5 * overview about any workload, CPU or specific PID. 5 * overview about any workload, CPU or specific PID.
6 * 6 *
7 * Sample output: 7 * Sample output:
8 8
9 $ perf stat ~/hackbench 10 9 $ perf stat ~/hackbench 10
10 Time: 0.104 10 Time: 0.104
11 11
12 Performance counter stats for '/home/mingo/hackbench': 12 Performance counter stats for '/home/mingo/hackbench':
13 13
14 1255.538611 task clock ticks # 10.143 CPU utilization factor 14 1255.538611 task clock ticks # 10.143 CPU utilization factor
15 54011 context switches # 0.043 M/sec 15 54011 context switches # 0.043 M/sec
16 385 CPU migrations # 0.000 M/sec 16 385 CPU migrations # 0.000 M/sec
17 17755 pagefaults # 0.014 M/sec 17 17755 pagefaults # 0.014 M/sec
18 3808323185 CPU cycles # 3033.219 M/sec 18 3808323185 CPU cycles # 3033.219 M/sec
19 1575111190 instructions # 1254.530 M/sec 19 1575111190 instructions # 1254.530 M/sec
20 17367895 cache references # 13.833 M/sec 20 17367895 cache references # 13.833 M/sec
21 7674421 cache misses # 6.112 M/sec 21 7674421 cache misses # 6.112 M/sec
22 22
23 Wall-clock time elapsed: 123.786620 msecs 23 Wall-clock time elapsed: 123.786620 msecs
24 24
25 * 25 *
26 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 26 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
27 * 27 *
28 * Improvements and fixes by: 28 * Improvements and fixes by:
29 * 29 *
30 * Arjan van de Ven <arjan@linux.intel.com> 30 * Arjan van de Ven <arjan@linux.intel.com>
31 * Yanmin Zhang <yanmin.zhang@intel.com> 31 * Yanmin Zhang <yanmin.zhang@intel.com>
32 * Wu Fengguang <fengguang.wu@intel.com> 32 * Wu Fengguang <fengguang.wu@intel.com>
33 * Mike Galbraith <efault@gmx.de> 33 * Mike Galbraith <efault@gmx.de>
34 * Paul Mackerras <paulus@samba.org> 34 * Paul Mackerras <paulus@samba.org>
35 * Jaswinder Singh Rajput <jaswinder@kernel.org> 35 * Jaswinder Singh Rajput <jaswinder@kernel.org>
36 * 36 *
37 * Released under the GPL v2. (and only v2, not any later version) 37 * Released under the GPL v2. (and only v2, not any later version)
38 */ 38 */
39 39
40 #include "perf.h" 40 #include "perf.h"
41 #include "builtin.h" 41 #include "builtin.h"
42 #include "util/util.h" 42 #include "util/util.h"
43 #include "util/parse-options.h" 43 #include "util/parse-options.h"
44 #include "util/parse-events.h" 44 #include "util/parse-events.h"
45 #include "util/event.h" 45 #include "util/event.h"
46 #include "util/debug.h" 46 #include "util/debug.h"
47 #include "util/header.h" 47 #include "util/header.h"
48 #include "util/cpumap.h"
48 49
49 #include <sys/prctl.h> 50 #include <sys/prctl.h>
50 #include <math.h> 51 #include <math.h>
51 52
52 static struct perf_event_attr default_attrs[] = { 53 static struct perf_event_attr default_attrs[] = {
53 54
54 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 55 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
55 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 56 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
56 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 57 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
57 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 58 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
58 59
59 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 60 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
60 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 61 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
61 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 62 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
62 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 63 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
63 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES }, 64 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES },
64 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES }, 65 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES },
65 66
66 }; 67 };
67 68
68 static int system_wide = 0; 69 static int system_wide = 0;
69 static unsigned int nr_cpus = 0; 70 static unsigned int nr_cpus = 0;
70 static int run_idx = 0; 71 static int run_idx = 0;
71 72
72 static int run_count = 1; 73 static int run_count = 1;
73 static int inherit = 1; 74 static int inherit = 1;
74 static int scale = 1; 75 static int scale = 1;
75 static pid_t target_pid = -1; 76 static pid_t target_pid = -1;
76 static pid_t child_pid = -1; 77 static pid_t child_pid = -1;
77 static int null_run = 0; 78 static int null_run = 0;
78 79
79 static int fd[MAX_NR_CPUS][MAX_COUNTERS]; 80 static int fd[MAX_NR_CPUS][MAX_COUNTERS];
80 81
81 static int event_scaled[MAX_COUNTERS]; 82 static int event_scaled[MAX_COUNTERS];
82 83
83 static volatile int done = 0; 84 static volatile int done = 0;
84 85
85 struct stats 86 struct stats
86 { 87 {
87 double n, mean, M2; 88 double n, mean, M2;
88 }; 89 };
89 90
90 static void update_stats(struct stats *stats, u64 val) 91 static void update_stats(struct stats *stats, u64 val)
91 { 92 {
92 double delta; 93 double delta;
93 94
94 stats->n++; 95 stats->n++;
95 delta = val - stats->mean; 96 delta = val - stats->mean;
96 stats->mean += delta / stats->n; 97 stats->mean += delta / stats->n;
97 stats->M2 += delta*(val - stats->mean); 98 stats->M2 += delta*(val - stats->mean);
98 } 99 }
99 100
100 static double avg_stats(struct stats *stats) 101 static double avg_stats(struct stats *stats)
101 { 102 {
102 return stats->mean; 103 return stats->mean;
103 } 104 }
104 105
105 /* 106 /*
106 * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance 107 * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
107 * 108 *
108 * (\Sum n_i^2) - ((\Sum n_i)^2)/n 109 * (\Sum n_i^2) - ((\Sum n_i)^2)/n
109 * s^2 = ------------------------------- 110 * s^2 = -------------------------------
110 * n - 1 111 * n - 1
111 * 112 *
112 * http://en.wikipedia.org/wiki/Stddev 113 * http://en.wikipedia.org/wiki/Stddev
113 * 114 *
114 * The std dev of the mean is related to the std dev by: 115 * The std dev of the mean is related to the std dev by:
115 * 116 *
116 * s 117 * s
117 * s_mean = ------- 118 * s_mean = -------
118 * sqrt(n) 119 * sqrt(n)
119 * 120 *
120 */ 121 */
121 static double stddev_stats(struct stats *stats) 122 static double stddev_stats(struct stats *stats)
122 { 123 {
123 double variance = stats->M2 / (stats->n - 1); 124 double variance = stats->M2 / (stats->n - 1);
124 double variance_mean = variance / stats->n; 125 double variance_mean = variance / stats->n;
125 126
126 return sqrt(variance_mean); 127 return sqrt(variance_mean);
127 } 128 }
128 129
129 struct stats event_res_stats[MAX_COUNTERS][3]; 130 struct stats event_res_stats[MAX_COUNTERS][3];
130 struct stats runtime_nsecs_stats; 131 struct stats runtime_nsecs_stats;
131 struct stats walltime_nsecs_stats; 132 struct stats walltime_nsecs_stats;
132 struct stats runtime_cycles_stats; 133 struct stats runtime_cycles_stats;
133 struct stats runtime_branches_stats; 134 struct stats runtime_branches_stats;
134 135
135 #define MATCH_EVENT(t, c, counter) \ 136 #define MATCH_EVENT(t, c, counter) \
136 (attrs[counter].type == PERF_TYPE_##t && \ 137 (attrs[counter].type == PERF_TYPE_##t && \
137 attrs[counter].config == PERF_COUNT_##c) 138 attrs[counter].config == PERF_COUNT_##c)
138 139
139 #define ERR_PERF_OPEN \ 140 #define ERR_PERF_OPEN \
140 "Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n" 141 "Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n"
141 142
142 static void create_perf_stat_counter(int counter, int pid) 143 static void create_perf_stat_counter(int counter, int pid)
143 { 144 {
144 struct perf_event_attr *attr = attrs + counter; 145 struct perf_event_attr *attr = attrs + counter;
145 146
146 if (scale) 147 if (scale)
147 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 148 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
148 PERF_FORMAT_TOTAL_TIME_RUNNING; 149 PERF_FORMAT_TOTAL_TIME_RUNNING;
149 150
150 if (system_wide) { 151 if (system_wide) {
151 unsigned int cpu; 152 unsigned int cpu;
152 153
153 for (cpu = 0; cpu < nr_cpus; cpu++) { 154 for (cpu = 0; cpu < nr_cpus; cpu++) {
154 fd[cpu][counter] = sys_perf_event_open(attr, -1, cpu, -1, 0); 155 fd[cpu][counter] = sys_perf_event_open(attr, -1, cpumap[cpu], -1, 0);
155 if (fd[cpu][counter] < 0 && verbose) 156 if (fd[cpu][counter] < 0 && verbose)
156 fprintf(stderr, ERR_PERF_OPEN, counter, 157 fprintf(stderr, ERR_PERF_OPEN, counter,
157 fd[cpu][counter], strerror(errno)); 158 fd[cpu][counter], strerror(errno));
158 } 159 }
159 } else { 160 } else {
160 attr->inherit = inherit; 161 attr->inherit = inherit;
161 attr->disabled = 1; 162 attr->disabled = 1;
162 attr->enable_on_exec = 1; 163 attr->enable_on_exec = 1;
163 164
164 fd[0][counter] = sys_perf_event_open(attr, pid, -1, -1, 0); 165 fd[0][counter] = sys_perf_event_open(attr, pid, -1, -1, 0);
165 if (fd[0][counter] < 0 && verbose) 166 if (fd[0][counter] < 0 && verbose)
166 fprintf(stderr, ERR_PERF_OPEN, counter, 167 fprintf(stderr, ERR_PERF_OPEN, counter,
167 fd[0][counter], strerror(errno)); 168 fd[0][counter], strerror(errno));
168 } 169 }
169 } 170 }
170 171
171 /* 172 /*
172 * Does the counter have nsecs as a unit? 173 * Does the counter have nsecs as a unit?
173 */ 174 */
174 static inline int nsec_counter(int counter) 175 static inline int nsec_counter(int counter)
175 { 176 {
176 if (MATCH_EVENT(SOFTWARE, SW_CPU_CLOCK, counter) || 177 if (MATCH_EVENT(SOFTWARE, SW_CPU_CLOCK, counter) ||
177 MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) 178 MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
178 return 1; 179 return 1;
179 180
180 return 0; 181 return 0;
181 } 182 }
182 183
183 /* 184 /*
184 * Read out the results of a single counter: 185 * Read out the results of a single counter:
185 */ 186 */
186 static void read_counter(int counter) 187 static void read_counter(int counter)
187 { 188 {
188 u64 count[3], single_count[3]; 189 u64 count[3], single_count[3];
189 unsigned int cpu; 190 unsigned int cpu;
190 size_t res, nv; 191 size_t res, nv;
191 int scaled; 192 int scaled;
192 int i; 193 int i;
193 194
194 count[0] = count[1] = count[2] = 0; 195 count[0] = count[1] = count[2] = 0;
195 196
196 nv = scale ? 3 : 1; 197 nv = scale ? 3 : 1;
197 for (cpu = 0; cpu < nr_cpus; cpu++) { 198 for (cpu = 0; cpu < nr_cpus; cpu++) {
198 if (fd[cpu][counter] < 0) 199 if (fd[cpu][counter] < 0)
199 continue; 200 continue;
200 201
201 res = read(fd[cpu][counter], single_count, nv * sizeof(u64)); 202 res = read(fd[cpu][counter], single_count, nv * sizeof(u64));
202 assert(res == nv * sizeof(u64)); 203 assert(res == nv * sizeof(u64));
203 204
204 close(fd[cpu][counter]); 205 close(fd[cpu][counter]);
205 fd[cpu][counter] = -1; 206 fd[cpu][counter] = -1;
206 207
207 count[0] += single_count[0]; 208 count[0] += single_count[0];
208 if (scale) { 209 if (scale) {
209 count[1] += single_count[1]; 210 count[1] += single_count[1];
210 count[2] += single_count[2]; 211 count[2] += single_count[2];
211 } 212 }
212 } 213 }
213 214
214 scaled = 0; 215 scaled = 0;
215 if (scale) { 216 if (scale) {
216 if (count[2] == 0) { 217 if (count[2] == 0) {
217 event_scaled[counter] = -1; 218 event_scaled[counter] = -1;
218 count[0] = 0; 219 count[0] = 0;
219 return; 220 return;
220 } 221 }
221 222
222 if (count[2] < count[1]) { 223 if (count[2] < count[1]) {
223 event_scaled[counter] = 1; 224 event_scaled[counter] = 1;
224 count[0] = (unsigned long long) 225 count[0] = (unsigned long long)
225 ((double)count[0] * count[1] / count[2] + 0.5); 226 ((double)count[0] * count[1] / count[2] + 0.5);
226 } 227 }
227 } 228 }
228 229
229 for (i = 0; i < 3; i++) 230 for (i = 0; i < 3; i++)
230 update_stats(&event_res_stats[counter][i], count[i]); 231 update_stats(&event_res_stats[counter][i], count[i]);
231 232
232 if (verbose) { 233 if (verbose) {
233 fprintf(stderr, "%s: %Ld %Ld %Ld\n", event_name(counter), 234 fprintf(stderr, "%s: %Ld %Ld %Ld\n", event_name(counter),
234 count[0], count[1], count[2]); 235 count[0], count[1], count[2]);
235 } 236 }
236 237
237 /* 238 /*
238 * Save the full runtime - to allow normalization during printout: 239 * Save the full runtime - to allow normalization during printout:
239 */ 240 */
240 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) 241 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
241 update_stats(&runtime_nsecs_stats, count[0]); 242 update_stats(&runtime_nsecs_stats, count[0]);
242 if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter)) 243 if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter))
243 update_stats(&runtime_cycles_stats, count[0]); 244 update_stats(&runtime_cycles_stats, count[0]);
244 if (MATCH_EVENT(HARDWARE, HW_BRANCH_INSTRUCTIONS, counter)) 245 if (MATCH_EVENT(HARDWARE, HW_BRANCH_INSTRUCTIONS, counter))
245 update_stats(&runtime_branches_stats, count[0]); 246 update_stats(&runtime_branches_stats, count[0]);
246 } 247 }
247 248
248 static int run_perf_stat(int argc __used, const char **argv) 249 static int run_perf_stat(int argc __used, const char **argv)
249 { 250 {
250 unsigned long long t0, t1; 251 unsigned long long t0, t1;
251 int status = 0; 252 int status = 0;
252 int counter; 253 int counter;
253 int pid = target_pid; 254 int pid = target_pid;
254 int child_ready_pipe[2], go_pipe[2]; 255 int child_ready_pipe[2], go_pipe[2];
255 const bool forks = (target_pid == -1 && argc > 0); 256 const bool forks = (target_pid == -1 && argc > 0);
256 char buf; 257 char buf;
257 258
258 if (!system_wide) 259 if (!system_wide)
259 nr_cpus = 1; 260 nr_cpus = 1;
260 261
261 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { 262 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
262 perror("failed to create pipes"); 263 perror("failed to create pipes");
263 exit(1); 264 exit(1);
264 } 265 }
265 266
266 if (forks) { 267 if (forks) {
267 if ((pid = fork()) < 0) 268 if ((pid = fork()) < 0)
268 perror("failed to fork"); 269 perror("failed to fork");
269 270
270 if (!pid) { 271 if (!pid) {
271 close(child_ready_pipe[0]); 272 close(child_ready_pipe[0]);
272 close(go_pipe[1]); 273 close(go_pipe[1]);
273 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 274 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
274 275
275 /* 276 /*
276 * Do a dummy execvp to get the PLT entry resolved, 277 * Do a dummy execvp to get the PLT entry resolved,
277 * so we avoid the resolver overhead on the real 278 * so we avoid the resolver overhead on the real
278 * execvp call. 279 * execvp call.
279 */ 280 */
280 execvp("", (char **)argv); 281 execvp("", (char **)argv);
281 282
282 /* 283 /*
283 * Tell the parent we're ready to go 284 * Tell the parent we're ready to go
284 */ 285 */
285 close(child_ready_pipe[1]); 286 close(child_ready_pipe[1]);
286 287
287 /* 288 /*
288 * Wait until the parent tells us to go. 289 * Wait until the parent tells us to go.
289 */ 290 */
290 if (read(go_pipe[0], &buf, 1) == -1) 291 if (read(go_pipe[0], &buf, 1) == -1)
291 perror("unable to read pipe"); 292 perror("unable to read pipe");
292 293
293 execvp(argv[0], (char **)argv); 294 execvp(argv[0], (char **)argv);
294 295
295 perror(argv[0]); 296 perror(argv[0]);
296 exit(-1); 297 exit(-1);
297 } 298 }
298 299
299 child_pid = pid; 300 child_pid = pid;
300 301
301 /* 302 /*
302 * Wait for the child to be ready to exec. 303 * Wait for the child to be ready to exec.
303 */ 304 */
304 close(child_ready_pipe[1]); 305 close(child_ready_pipe[1]);
305 close(go_pipe[0]); 306 close(go_pipe[0]);
306 if (read(child_ready_pipe[0], &buf, 1) == -1) 307 if (read(child_ready_pipe[0], &buf, 1) == -1)
307 perror("unable to read pipe"); 308 perror("unable to read pipe");
308 close(child_ready_pipe[0]); 309 close(child_ready_pipe[0]);
309 } 310 }
310 311
311 for (counter = 0; counter < nr_counters; counter++) 312 for (counter = 0; counter < nr_counters; counter++)
312 create_perf_stat_counter(counter, pid); 313 create_perf_stat_counter(counter, pid);
313 314
314 /* 315 /*
315 * Enable counters and exec the command: 316 * Enable counters and exec the command:
316 */ 317 */
317 t0 = rdclock(); 318 t0 = rdclock();
318 319
319 if (forks) { 320 if (forks) {
320 close(go_pipe[1]); 321 close(go_pipe[1]);
321 wait(&status); 322 wait(&status);
322 } else { 323 } else {
323 while(!done); 324 while(!done);
324 } 325 }
325 326
326 t1 = rdclock(); 327 t1 = rdclock();
327 328
328 update_stats(&walltime_nsecs_stats, t1 - t0); 329 update_stats(&walltime_nsecs_stats, t1 - t0);
329 330
330 for (counter = 0; counter < nr_counters; counter++) 331 for (counter = 0; counter < nr_counters; counter++)
331 read_counter(counter); 332 read_counter(counter);
332 333
333 return WEXITSTATUS(status); 334 return WEXITSTATUS(status);
334 } 335 }
335 336
336 static void print_noise(int counter, double avg) 337 static void print_noise(int counter, double avg)
337 { 338 {
338 if (run_count == 1) 339 if (run_count == 1)
339 return; 340 return;
340 341
341 fprintf(stderr, " ( +- %7.3f%% )", 342 fprintf(stderr, " ( +- %7.3f%% )",
342 100 * stddev_stats(&event_res_stats[counter][0]) / avg); 343 100 * stddev_stats(&event_res_stats[counter][0]) / avg);
343 } 344 }
344 345
345 static void nsec_printout(int counter, double avg) 346 static void nsec_printout(int counter, double avg)
346 { 347 {
347 double msecs = avg / 1e6; 348 double msecs = avg / 1e6;
348 349
349 fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter)); 350 fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter));
350 351
351 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) { 352 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) {
352 fprintf(stderr, " # %10.3f CPUs ", 353 fprintf(stderr, " # %10.3f CPUs ",
353 avg / avg_stats(&walltime_nsecs_stats)); 354 avg / avg_stats(&walltime_nsecs_stats));
354 } 355 }
355 } 356 }
356 357
357 static void abs_printout(int counter, double avg) 358 static void abs_printout(int counter, double avg)
358 { 359 {
359 double total, ratio = 0.0; 360 double total, ratio = 0.0;
360 361
361 fprintf(stderr, " %14.0f %-24s", avg, event_name(counter)); 362 fprintf(stderr, " %14.0f %-24s", avg, event_name(counter));
362 363
363 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) { 364 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) {
364 total = avg_stats(&runtime_cycles_stats); 365 total = avg_stats(&runtime_cycles_stats);
365 366
366 if (total) 367 if (total)
367 ratio = avg / total; 368 ratio = avg / total;
368 369
369 fprintf(stderr, " # %10.3f IPC ", ratio); 370 fprintf(stderr, " # %10.3f IPC ", ratio);
370 } else if (MATCH_EVENT(HARDWARE, HW_BRANCH_MISSES, counter) && 371 } else if (MATCH_EVENT(HARDWARE, HW_BRANCH_MISSES, counter) &&
371 runtime_branches_stats.n != 0) { 372 runtime_branches_stats.n != 0) {
372 total = avg_stats(&runtime_branches_stats); 373 total = avg_stats(&runtime_branches_stats);
373 374
374 if (total) 375 if (total)
375 ratio = avg * 100 / total; 376 ratio = avg * 100 / total;
376 377
377 fprintf(stderr, " # %10.3f %% ", ratio); 378 fprintf(stderr, " # %10.3f %% ", ratio);
378 379
379 } else if (runtime_nsecs_stats.n != 0) { 380 } else if (runtime_nsecs_stats.n != 0) {
380 total = avg_stats(&runtime_nsecs_stats); 381 total = avg_stats(&runtime_nsecs_stats);
381 382
382 if (total) 383 if (total)
383 ratio = 1000.0 * avg / total; 384 ratio = 1000.0 * avg / total;
384 385
385 fprintf(stderr, " # %10.3f M/sec", ratio); 386 fprintf(stderr, " # %10.3f M/sec", ratio);
386 } 387 }
387 } 388 }
388 389
389 /* 390 /*
390 * Print out the results of a single counter: 391 * Print out the results of a single counter:
391 */ 392 */
392 static void print_counter(int counter) 393 static void print_counter(int counter)
393 { 394 {
394 double avg = avg_stats(&event_res_stats[counter][0]); 395 double avg = avg_stats(&event_res_stats[counter][0]);
395 int scaled = event_scaled[counter]; 396 int scaled = event_scaled[counter];
396 397
397 if (scaled == -1) { 398 if (scaled == -1) {
398 fprintf(stderr, " %14s %-24s\n", 399 fprintf(stderr, " %14s %-24s\n",
399 "<not counted>", event_name(counter)); 400 "<not counted>", event_name(counter));
400 return; 401 return;
401 } 402 }
402 403
403 if (nsec_counter(counter)) 404 if (nsec_counter(counter))
404 nsec_printout(counter, avg); 405 nsec_printout(counter, avg);
405 else 406 else
406 abs_printout(counter, avg); 407 abs_printout(counter, avg);
407 408
408 print_noise(counter, avg); 409 print_noise(counter, avg);
409 410
410 if (scaled) { 411 if (scaled) {
411 double avg_enabled, avg_running; 412 double avg_enabled, avg_running;
412 413
413 avg_enabled = avg_stats(&event_res_stats[counter][1]); 414 avg_enabled = avg_stats(&event_res_stats[counter][1]);
414 avg_running = avg_stats(&event_res_stats[counter][2]); 415 avg_running = avg_stats(&event_res_stats[counter][2]);
415 416
416 fprintf(stderr, " (scaled from %.2f%%)", 417 fprintf(stderr, " (scaled from %.2f%%)",
417 100 * avg_running / avg_enabled); 418 100 * avg_running / avg_enabled);
418 } 419 }
419 420
420 fprintf(stderr, "\n"); 421 fprintf(stderr, "\n");
421 } 422 }
422 423
423 static void print_stat(int argc, const char **argv) 424 static void print_stat(int argc, const char **argv)
424 { 425 {
425 int i, counter; 426 int i, counter;
426 427
427 fflush(stdout); 428 fflush(stdout);
428 429
429 fprintf(stderr, "\n"); 430 fprintf(stderr, "\n");
430 fprintf(stderr, " Performance counter stats for "); 431 fprintf(stderr, " Performance counter stats for ");
431 if(target_pid == -1) { 432 if(target_pid == -1) {
432 fprintf(stderr, "\'%s", argv[0]); 433 fprintf(stderr, "\'%s", argv[0]);
433 for (i = 1; i < argc; i++) 434 for (i = 1; i < argc; i++)
434 fprintf(stderr, " %s", argv[i]); 435 fprintf(stderr, " %s", argv[i]);
435 }else 436 }else
436 fprintf(stderr, "task pid \'%d", target_pid); 437 fprintf(stderr, "task pid \'%d", target_pid);
437 438
438 fprintf(stderr, "\'"); 439 fprintf(stderr, "\'");
439 if (run_count > 1) 440 if (run_count > 1)
440 fprintf(stderr, " (%d runs)", run_count); 441 fprintf(stderr, " (%d runs)", run_count);
441 fprintf(stderr, ":\n\n"); 442 fprintf(stderr, ":\n\n");
442 443
443 for (counter = 0; counter < nr_counters; counter++) 444 for (counter = 0; counter < nr_counters; counter++)
444 print_counter(counter); 445 print_counter(counter);
445 446
446 fprintf(stderr, "\n"); 447 fprintf(stderr, "\n");
447 fprintf(stderr, " %14.9f seconds time elapsed", 448 fprintf(stderr, " %14.9f seconds time elapsed",
448 avg_stats(&walltime_nsecs_stats)/1e9); 449 avg_stats(&walltime_nsecs_stats)/1e9);
449 if (run_count > 1) { 450 if (run_count > 1) {
450 fprintf(stderr, " ( +- %7.3f%% )", 451 fprintf(stderr, " ( +- %7.3f%% )",
451 100*stddev_stats(&walltime_nsecs_stats) / 452 100*stddev_stats(&walltime_nsecs_stats) /
452 avg_stats(&walltime_nsecs_stats)); 453 avg_stats(&walltime_nsecs_stats));
453 } 454 }
454 fprintf(stderr, "\n\n"); 455 fprintf(stderr, "\n\n");
455 } 456 }
456 457
457 static volatile int signr = -1; 458 static volatile int signr = -1;
458 459
459 static void skip_signal(int signo) 460 static void skip_signal(int signo)
460 { 461 {
461 if(target_pid != -1) 462 if(target_pid != -1)
462 done = 1; 463 done = 1;
463 464
464 signr = signo; 465 signr = signo;
465 } 466 }
466 467
467 static void sig_atexit(void) 468 static void sig_atexit(void)
468 { 469 {
469 if (child_pid != -1) 470 if (child_pid != -1)
470 kill(child_pid, SIGTERM); 471 kill(child_pid, SIGTERM);
471 472
472 if (signr == -1) 473 if (signr == -1)
473 return; 474 return;
474 475
475 signal(signr, SIG_DFL); 476 signal(signr, SIG_DFL);
476 kill(getpid(), signr); 477 kill(getpid(), signr);
477 } 478 }
478 479
479 static const char * const stat_usage[] = { 480 static const char * const stat_usage[] = {
480 "perf stat [<options>] [<command>]", 481 "perf stat [<options>] [<command>]",
481 NULL 482 NULL
482 }; 483 };
483 484
484 static const struct option options[] = { 485 static const struct option options[] = {
485 OPT_CALLBACK('e', "event", NULL, "event", 486 OPT_CALLBACK('e', "event", NULL, "event",
486 "event selector. use 'perf list' to list available events", 487 "event selector. use 'perf list' to list available events",
487 parse_events), 488 parse_events),
488 OPT_BOOLEAN('i', "inherit", &inherit, 489 OPT_BOOLEAN('i', "inherit", &inherit,
489 "child tasks inherit counters"), 490 "child tasks inherit counters"),
490 OPT_INTEGER('p', "pid", &target_pid, 491 OPT_INTEGER('p', "pid", &target_pid,
491 "stat events on existing pid"), 492 "stat events on existing pid"),
492 OPT_BOOLEAN('a', "all-cpus", &system_wide, 493 OPT_BOOLEAN('a', "all-cpus", &system_wide,
493 "system-wide collection from all CPUs"), 494 "system-wide collection from all CPUs"),
494 OPT_BOOLEAN('c', "scale", &scale, 495 OPT_BOOLEAN('c', "scale", &scale,
495 "scale/normalize counters"), 496 "scale/normalize counters"),
496 OPT_BOOLEAN('v', "verbose", &verbose, 497 OPT_BOOLEAN('v', "verbose", &verbose,
497 "be more verbose (show counter open errors, etc)"), 498 "be more verbose (show counter open errors, etc)"),
498 OPT_INTEGER('r', "repeat", &run_count, 499 OPT_INTEGER('r', "repeat", &run_count,
499 "repeat command and print average + stddev (max: 100)"), 500 "repeat command and print average + stddev (max: 100)"),
500 OPT_BOOLEAN('n', "null", &null_run, 501 OPT_BOOLEAN('n', "null", &null_run,
501 "null run - dont start any counters"), 502 "null run - dont start any counters"),
502 OPT_END() 503 OPT_END()
503 }; 504 };
504 505
505 int cmd_stat(int argc, const char **argv, const char *prefix __used) 506 int cmd_stat(int argc, const char **argv, const char *prefix __used)
506 { 507 {
507 int status; 508 int status;
508 509
509 argc = parse_options(argc, argv, options, stat_usage, 510 argc = parse_options(argc, argv, options, stat_usage,
510 PARSE_OPT_STOP_AT_NON_OPTION); 511 PARSE_OPT_STOP_AT_NON_OPTION);
511 if (!argc && target_pid == -1) 512 if (!argc && target_pid == -1)
512 usage_with_options(stat_usage, options); 513 usage_with_options(stat_usage, options);
513 if (run_count <= 0) 514 if (run_count <= 0)
514 usage_with_options(stat_usage, options); 515 usage_with_options(stat_usage, options);
515 516
516 /* Set attrs and nr_counters if no event is selected and !null_run */ 517 /* Set attrs and nr_counters if no event is selected and !null_run */
517 if (!null_run && !nr_counters) { 518 if (!null_run && !nr_counters) {
518 memcpy(attrs, default_attrs, sizeof(default_attrs)); 519 memcpy(attrs, default_attrs, sizeof(default_attrs));
519 nr_counters = ARRAY_SIZE(default_attrs); 520 nr_counters = ARRAY_SIZE(default_attrs);
520 } 521 }
521 522
522 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); 523 if (system_wide)
523 assert(nr_cpus <= MAX_NR_CPUS); 524 nr_cpus = read_cpu_map();
524 assert((int)nr_cpus >= 0); 525 else
526 nr_cpus = 1;
525 527
526 /* 528 /*
527 * We dont want to block the signals - that would cause 529 * We dont want to block the signals - that would cause
528 * child tasks to inherit that and Ctrl-C would not work. 530 * child tasks to inherit that and Ctrl-C would not work.
529 * What we want is for Ctrl-C to work in the exec()-ed 531 * What we want is for Ctrl-C to work in the exec()-ed
530 * task, but being ignored by perf stat itself: 532 * task, but being ignored by perf stat itself:
531 */ 533 */
532 atexit(sig_atexit); 534 atexit(sig_atexit);
533 signal(SIGINT, skip_signal); 535 signal(SIGINT, skip_signal);
534 signal(SIGALRM, skip_signal); 536 signal(SIGALRM, skip_signal);
535 signal(SIGABRT, skip_signal); 537 signal(SIGABRT, skip_signal);
536 538
537 status = 0; 539 status = 0;
538 for (run_idx = 0; run_idx < run_count; run_idx++) { 540 for (run_idx = 0; run_idx < run_count; run_idx++) {
539 if (run_count != 1 && verbose) 541 if (run_count != 1 && verbose)
540 fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); 542 fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1);
541 status = run_perf_stat(argc, argv); 543 status = run_perf_stat(argc, argv);
542 } 544 }
543 545
544 print_stat(argc, argv); 546 print_stat(argc, argv);
545 547
546 return status; 548 return status;
547 } 549 }
548 550
tools/perf/builtin-top.c
1 /* 1 /*
2 * builtin-top.c 2 * builtin-top.c
3 * 3 *
4 * Builtin top command: Display a continuously updated profile of 4 * Builtin top command: Display a continuously updated profile of
5 * any workload, CPU or specific PID. 5 * any workload, CPU or specific PID.
6 * 6 *
7 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 7 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
8 * 8 *
9 * Improvements and fixes by: 9 * Improvements and fixes by:
10 * 10 *
11 * Arjan van de Ven <arjan@linux.intel.com> 11 * Arjan van de Ven <arjan@linux.intel.com>
12 * Yanmin Zhang <yanmin.zhang@intel.com> 12 * Yanmin Zhang <yanmin.zhang@intel.com>
13 * Wu Fengguang <fengguang.wu@intel.com> 13 * Wu Fengguang <fengguang.wu@intel.com>
14 * Mike Galbraith <efault@gmx.de> 14 * Mike Galbraith <efault@gmx.de>
15 * Paul Mackerras <paulus@samba.org> 15 * Paul Mackerras <paulus@samba.org>
16 * 16 *
17 * Released under the GPL v2. (and only v2, not any later version) 17 * Released under the GPL v2. (and only v2, not any later version)
18 */ 18 */
19 #include "builtin.h" 19 #include "builtin.h"
20 20
21 #include "perf.h" 21 #include "perf.h"
22 22
23 #include "util/color.h" 23 #include "util/color.h"
24 #include "util/session.h" 24 #include "util/session.h"
25 #include "util/symbol.h" 25 #include "util/symbol.h"
26 #include "util/thread.h" 26 #include "util/thread.h"
27 #include "util/util.h" 27 #include "util/util.h"
28 #include <linux/rbtree.h> 28 #include <linux/rbtree.h>
29 #include "util/parse-options.h" 29 #include "util/parse-options.h"
30 #include "util/parse-events.h" 30 #include "util/parse-events.h"
31 #include "util/cpumap.h"
31 32
32 #include "util/debug.h" 33 #include "util/debug.h"
33 34
34 #include <assert.h> 35 #include <assert.h>
35 #include <fcntl.h> 36 #include <fcntl.h>
36 37
37 #include <stdio.h> 38 #include <stdio.h>
38 #include <termios.h> 39 #include <termios.h>
39 #include <unistd.h> 40 #include <unistd.h>
40 41
41 #include <errno.h> 42 #include <errno.h>
42 #include <time.h> 43 #include <time.h>
43 #include <sched.h> 44 #include <sched.h>
44 #include <pthread.h> 45 #include <pthread.h>
45 46
46 #include <sys/syscall.h> 47 #include <sys/syscall.h>
47 #include <sys/ioctl.h> 48 #include <sys/ioctl.h>
48 #include <sys/poll.h> 49 #include <sys/poll.h>
49 #include <sys/prctl.h> 50 #include <sys/prctl.h>
50 #include <sys/wait.h> 51 #include <sys/wait.h>
51 #include <sys/uio.h> 52 #include <sys/uio.h>
52 #include <sys/mman.h> 53 #include <sys/mman.h>
53 54
54 #include <linux/unistd.h> 55 #include <linux/unistd.h>
55 #include <linux/types.h> 56 #include <linux/types.h>
56 57
57 static int fd[MAX_NR_CPUS][MAX_COUNTERS]; 58 static int fd[MAX_NR_CPUS][MAX_COUNTERS];
58 59
59 static int system_wide = 0; 60 static int system_wide = 0;
60 61
61 static int default_interval = 0; 62 static int default_interval = 0;
62 63
63 static int count_filter = 5; 64 static int count_filter = 5;
64 static int print_entries; 65 static int print_entries;
65 66
66 static int target_pid = -1; 67 static int target_pid = -1;
67 static int inherit = 0; 68 static int inherit = 0;
68 static int profile_cpu = -1; 69 static int profile_cpu = -1;
69 static int nr_cpus = 0; 70 static int nr_cpus = 0;
70 static unsigned int realtime_prio = 0; 71 static unsigned int realtime_prio = 0;
71 static int group = 0; 72 static int group = 0;
72 static unsigned int page_size; 73 static unsigned int page_size;
73 static unsigned int mmap_pages = 16; 74 static unsigned int mmap_pages = 16;
74 static int freq = 1000; /* 1 KHz */ 75 static int freq = 1000; /* 1 KHz */
75 76
76 static int delay_secs = 2; 77 static int delay_secs = 2;
77 static int zero = 0; 78 static int zero = 0;
78 static int dump_symtab = 0; 79 static int dump_symtab = 0;
79 80
80 static bool hide_kernel_symbols = false; 81 static bool hide_kernel_symbols = false;
81 static bool hide_user_symbols = false; 82 static bool hide_user_symbols = false;
82 static struct winsize winsize; 83 static struct winsize winsize;
83 84
84 /* 85 /*
85 * Source 86 * Source
86 */ 87 */
87 88
88 struct source_line { 89 struct source_line {
89 u64 eip; 90 u64 eip;
90 unsigned long count[MAX_COUNTERS]; 91 unsigned long count[MAX_COUNTERS];
91 char *line; 92 char *line;
92 struct source_line *next; 93 struct source_line *next;
93 }; 94 };
94 95
95 static char *sym_filter = NULL; 96 static char *sym_filter = NULL;
96 struct sym_entry *sym_filter_entry = NULL; 97 struct sym_entry *sym_filter_entry = NULL;
97 struct sym_entry *sym_filter_entry_sched = NULL; 98 struct sym_entry *sym_filter_entry_sched = NULL;
98 static int sym_pcnt_filter = 5; 99 static int sym_pcnt_filter = 5;
99 static int sym_counter = 0; 100 static int sym_counter = 0;
100 static int display_weighted = -1; 101 static int display_weighted = -1;
101 102
102 /* 103 /*
103 * Symbols 104 * Symbols
104 */ 105 */
105 106
106 struct sym_entry_source { 107 struct sym_entry_source {
107 struct source_line *source; 108 struct source_line *source;
108 struct source_line *lines; 109 struct source_line *lines;
109 struct source_line **lines_tail; 110 struct source_line **lines_tail;
110 pthread_mutex_t lock; 111 pthread_mutex_t lock;
111 }; 112 };
112 113
113 struct sym_entry { 114 struct sym_entry {
114 struct rb_node rb_node; 115 struct rb_node rb_node;
115 struct list_head node; 116 struct list_head node;
116 unsigned long snap_count; 117 unsigned long snap_count;
117 double weight; 118 double weight;
118 int skip; 119 int skip;
119 u16 name_len; 120 u16 name_len;
120 u8 origin; 121 u8 origin;
121 struct map *map; 122 struct map *map;
122 struct sym_entry_source *src; 123 struct sym_entry_source *src;
123 unsigned long count[0]; 124 unsigned long count[0];
124 }; 125 };
125 126
126 /* 127 /*
127 * Source functions 128 * Source functions
128 */ 129 */
129 130
130 static inline struct symbol *sym_entry__symbol(struct sym_entry *self) 131 static inline struct symbol *sym_entry__symbol(struct sym_entry *self)
131 { 132 {
132 return ((void *)self) + symbol_conf.priv_size; 133 return ((void *)self) + symbol_conf.priv_size;
133 } 134 }
134 135
135 static void get_term_dimensions(struct winsize *ws) 136 static void get_term_dimensions(struct winsize *ws)
136 { 137 {
137 char *s = getenv("LINES"); 138 char *s = getenv("LINES");
138 139
139 if (s != NULL) { 140 if (s != NULL) {
140 ws->ws_row = atoi(s); 141 ws->ws_row = atoi(s);
141 s = getenv("COLUMNS"); 142 s = getenv("COLUMNS");
142 if (s != NULL) { 143 if (s != NULL) {
143 ws->ws_col = atoi(s); 144 ws->ws_col = atoi(s);
144 if (ws->ws_row && ws->ws_col) 145 if (ws->ws_row && ws->ws_col)
145 return; 146 return;
146 } 147 }
147 } 148 }
148 #ifdef TIOCGWINSZ 149 #ifdef TIOCGWINSZ
149 if (ioctl(1, TIOCGWINSZ, ws) == 0 && 150 if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
150 ws->ws_row && ws->ws_col) 151 ws->ws_row && ws->ws_col)
151 return; 152 return;
152 #endif 153 #endif
153 ws->ws_row = 25; 154 ws->ws_row = 25;
154 ws->ws_col = 80; 155 ws->ws_col = 80;
155 } 156 }
156 157
157 static void update_print_entries(struct winsize *ws) 158 static void update_print_entries(struct winsize *ws)
158 { 159 {
159 print_entries = ws->ws_row; 160 print_entries = ws->ws_row;
160 161
161 if (print_entries > 9) 162 if (print_entries > 9)
162 print_entries -= 9; 163 print_entries -= 9;
163 } 164 }
164 165
165 static void sig_winch_handler(int sig __used) 166 static void sig_winch_handler(int sig __used)
166 { 167 {
167 get_term_dimensions(&winsize); 168 get_term_dimensions(&winsize);
168 update_print_entries(&winsize); 169 update_print_entries(&winsize);
169 } 170 }
170 171
171 static void parse_source(struct sym_entry *syme) 172 static void parse_source(struct sym_entry *syme)
172 { 173 {
173 struct symbol *sym; 174 struct symbol *sym;
174 struct sym_entry_source *source; 175 struct sym_entry_source *source;
175 struct map *map; 176 struct map *map;
176 FILE *file; 177 FILE *file;
177 char command[PATH_MAX*2]; 178 char command[PATH_MAX*2];
178 const char *path; 179 const char *path;
179 u64 len; 180 u64 len;
180 181
181 if (!syme) 182 if (!syme)
182 return; 183 return;
183 184
184 if (syme->src == NULL) { 185 if (syme->src == NULL) {
185 syme->src = zalloc(sizeof(*source)); 186 syme->src = zalloc(sizeof(*source));
186 if (syme->src == NULL) 187 if (syme->src == NULL)
187 return; 188 return;
188 pthread_mutex_init(&syme->src->lock, NULL); 189 pthread_mutex_init(&syme->src->lock, NULL);
189 } 190 }
190 191
191 source = syme->src; 192 source = syme->src;
192 193
193 if (source->lines) { 194 if (source->lines) {
194 pthread_mutex_lock(&source->lock); 195 pthread_mutex_lock(&source->lock);
195 goto out_assign; 196 goto out_assign;
196 } 197 }
197 198
198 sym = sym_entry__symbol(syme); 199 sym = sym_entry__symbol(syme);
199 map = syme->map; 200 map = syme->map;
200 path = map->dso->long_name; 201 path = map->dso->long_name;
201 202
202 len = sym->end - sym->start; 203 len = sym->end - sym->start;
203 204
204 sprintf(command, 205 sprintf(command,
205 "objdump --start-address=%#0*Lx --stop-address=%#0*Lx -dS %s", 206 "objdump --start-address=%#0*Lx --stop-address=%#0*Lx -dS %s",
206 BITS_PER_LONG / 4, map__rip_2objdump(map, sym->start), 207 BITS_PER_LONG / 4, map__rip_2objdump(map, sym->start),
207 BITS_PER_LONG / 4, map__rip_2objdump(map, sym->end), path); 208 BITS_PER_LONG / 4, map__rip_2objdump(map, sym->end), path);
208 209
209 file = popen(command, "r"); 210 file = popen(command, "r");
210 if (!file) 211 if (!file)
211 return; 212 return;
212 213
213 pthread_mutex_lock(&source->lock); 214 pthread_mutex_lock(&source->lock);
214 source->lines_tail = &source->lines; 215 source->lines_tail = &source->lines;
215 while (!feof(file)) { 216 while (!feof(file)) {
216 struct source_line *src; 217 struct source_line *src;
217 size_t dummy = 0; 218 size_t dummy = 0;
218 char *c, *sep; 219 char *c, *sep;
219 220
220 src = malloc(sizeof(struct source_line)); 221 src = malloc(sizeof(struct source_line));
221 assert(src != NULL); 222 assert(src != NULL);
222 memset(src, 0, sizeof(struct source_line)); 223 memset(src, 0, sizeof(struct source_line));
223 224
224 if (getline(&src->line, &dummy, file) < 0) 225 if (getline(&src->line, &dummy, file) < 0)
225 break; 226 break;
226 if (!src->line) 227 if (!src->line)
227 break; 228 break;
228 229
229 c = strchr(src->line, '\n'); 230 c = strchr(src->line, '\n');
230 if (c) 231 if (c)
231 *c = 0; 232 *c = 0;
232 233
233 src->next = NULL; 234 src->next = NULL;
234 *source->lines_tail = src; 235 *source->lines_tail = src;
235 source->lines_tail = &src->next; 236 source->lines_tail = &src->next;
236 237
237 src->eip = strtoull(src->line, &sep, 16); 238 src->eip = strtoull(src->line, &sep, 16);
238 if (*sep == ':') 239 if (*sep == ':')
239 src->eip = map__objdump_2ip(map, src->eip); 240 src->eip = map__objdump_2ip(map, src->eip);
240 else /* this line has no ip info (e.g. source line) */ 241 else /* this line has no ip info (e.g. source line) */
241 src->eip = 0; 242 src->eip = 0;
242 } 243 }
243 pclose(file); 244 pclose(file);
244 out_assign: 245 out_assign:
245 sym_filter_entry = syme; 246 sym_filter_entry = syme;
246 pthread_mutex_unlock(&source->lock); 247 pthread_mutex_unlock(&source->lock);
247 } 248 }
248 249
249 static void __zero_source_counters(struct sym_entry *syme) 250 static void __zero_source_counters(struct sym_entry *syme)
250 { 251 {
251 int i; 252 int i;
252 struct source_line *line; 253 struct source_line *line;
253 254
254 line = syme->src->lines; 255 line = syme->src->lines;
255 while (line) { 256 while (line) {
256 for (i = 0; i < nr_counters; i++) 257 for (i = 0; i < nr_counters; i++)
257 line->count[i] = 0; 258 line->count[i] = 0;
258 line = line->next; 259 line = line->next;
259 } 260 }
260 } 261 }
261 262
262 static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) 263 static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
263 { 264 {
264 struct source_line *line; 265 struct source_line *line;
265 266
266 if (syme != sym_filter_entry) 267 if (syme != sym_filter_entry)
267 return; 268 return;
268 269
269 if (pthread_mutex_trylock(&syme->src->lock)) 270 if (pthread_mutex_trylock(&syme->src->lock))
270 return; 271 return;
271 272
272 if (syme->src == NULL || syme->src->source == NULL) 273 if (syme->src == NULL || syme->src->source == NULL)
273 goto out_unlock; 274 goto out_unlock;
274 275
275 for (line = syme->src->lines; line; line = line->next) { 276 for (line = syme->src->lines; line; line = line->next) {
276 /* skip lines without IP info */ 277 /* skip lines without IP info */
277 if (line->eip == 0) 278 if (line->eip == 0)
278 continue; 279 continue;
279 if (line->eip == ip) { 280 if (line->eip == ip) {
280 line->count[counter]++; 281 line->count[counter]++;
281 break; 282 break;
282 } 283 }
283 if (line->eip > ip) 284 if (line->eip > ip)
284 break; 285 break;
285 } 286 }
286 out_unlock: 287 out_unlock:
287 pthread_mutex_unlock(&syme->src->lock); 288 pthread_mutex_unlock(&syme->src->lock);
288 } 289 }
289 290
290 #define PATTERN_LEN (BITS_PER_LONG / 4 + 2) 291 #define PATTERN_LEN (BITS_PER_LONG / 4 + 2)
291 292
292 static void lookup_sym_source(struct sym_entry *syme) 293 static void lookup_sym_source(struct sym_entry *syme)
293 { 294 {
294 struct symbol *symbol = sym_entry__symbol(syme); 295 struct symbol *symbol = sym_entry__symbol(syme);
295 struct source_line *line; 296 struct source_line *line;
296 char pattern[PATTERN_LEN + 1]; 297 char pattern[PATTERN_LEN + 1];
297 298
298 sprintf(pattern, "%0*Lx <", BITS_PER_LONG / 4, 299 sprintf(pattern, "%0*Lx <", BITS_PER_LONG / 4,
299 map__rip_2objdump(syme->map, symbol->start)); 300 map__rip_2objdump(syme->map, symbol->start));
300 301
301 pthread_mutex_lock(&syme->src->lock); 302 pthread_mutex_lock(&syme->src->lock);
302 for (line = syme->src->lines; line; line = line->next) { 303 for (line = syme->src->lines; line; line = line->next) {
303 if (memcmp(line->line, pattern, PATTERN_LEN) == 0) { 304 if (memcmp(line->line, pattern, PATTERN_LEN) == 0) {
304 syme->src->source = line; 305 syme->src->source = line;
305 break; 306 break;
306 } 307 }
307 } 308 }
308 pthread_mutex_unlock(&syme->src->lock); 309 pthread_mutex_unlock(&syme->src->lock);
309 } 310 }
310 311
311 static void show_lines(struct source_line *queue, int count, int total) 312 static void show_lines(struct source_line *queue, int count, int total)
312 { 313 {
313 int i; 314 int i;
314 struct source_line *line; 315 struct source_line *line;
315 316
316 line = queue; 317 line = queue;
317 for (i = 0; i < count; i++) { 318 for (i = 0; i < count; i++) {
318 float pcnt = 100.0*(float)line->count[sym_counter]/(float)total; 319 float pcnt = 100.0*(float)line->count[sym_counter]/(float)total;
319 320
320 printf("%8li %4.1f%%\t%s\n", line->count[sym_counter], pcnt, line->line); 321 printf("%8li %4.1f%%\t%s\n", line->count[sym_counter], pcnt, line->line);
321 line = line->next; 322 line = line->next;
322 } 323 }
323 } 324 }
324 325
325 #define TRACE_COUNT 3 326 #define TRACE_COUNT 3
326 327
327 static void show_details(struct sym_entry *syme) 328 static void show_details(struct sym_entry *syme)
328 { 329 {
329 struct symbol *symbol; 330 struct symbol *symbol;
330 struct source_line *line; 331 struct source_line *line;
331 struct source_line *line_queue = NULL; 332 struct source_line *line_queue = NULL;
332 int displayed = 0; 333 int displayed = 0;
333 int line_queue_count = 0, total = 0, more = 0; 334 int line_queue_count = 0, total = 0, more = 0;
334 335
335 if (!syme) 336 if (!syme)
336 return; 337 return;
337 338
338 if (!syme->src->source) 339 if (!syme->src->source)
339 lookup_sym_source(syme); 340 lookup_sym_source(syme);
340 341
341 if (!syme->src->source) 342 if (!syme->src->source)
342 return; 343 return;
343 344
344 symbol = sym_entry__symbol(syme); 345 symbol = sym_entry__symbol(syme);
345 printf("Showing %s for %s\n", event_name(sym_counter), symbol->name); 346 printf("Showing %s for %s\n", event_name(sym_counter), symbol->name);
346 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); 347 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
347 348
348 pthread_mutex_lock(&syme->src->lock); 349 pthread_mutex_lock(&syme->src->lock);
349 line = syme->src->source; 350 line = syme->src->source;
350 while (line) { 351 while (line) {
351 total += line->count[sym_counter]; 352 total += line->count[sym_counter];
352 line = line->next; 353 line = line->next;
353 } 354 }
354 355
355 line = syme->src->source; 356 line = syme->src->source;
356 while (line) { 357 while (line) {
357 float pcnt = 0.0; 358 float pcnt = 0.0;
358 359
359 if (!line_queue_count) 360 if (!line_queue_count)
360 line_queue = line; 361 line_queue = line;
361 line_queue_count++; 362 line_queue_count++;
362 363
363 if (line->count[sym_counter]) 364 if (line->count[sym_counter])
364 pcnt = 100.0 * line->count[sym_counter] / (float)total; 365 pcnt = 100.0 * line->count[sym_counter] / (float)total;
365 if (pcnt >= (float)sym_pcnt_filter) { 366 if (pcnt >= (float)sym_pcnt_filter) {
366 if (displayed <= print_entries) 367 if (displayed <= print_entries)
367 show_lines(line_queue, line_queue_count, total); 368 show_lines(line_queue, line_queue_count, total);
368 else more++; 369 else more++;
369 displayed += line_queue_count; 370 displayed += line_queue_count;
370 line_queue_count = 0; 371 line_queue_count = 0;
371 line_queue = NULL; 372 line_queue = NULL;
372 } else if (line_queue_count > TRACE_COUNT) { 373 } else if (line_queue_count > TRACE_COUNT) {
373 line_queue = line_queue->next; 374 line_queue = line_queue->next;
374 line_queue_count--; 375 line_queue_count--;
375 } 376 }
376 377
377 line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8; 378 line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8;
378 line = line->next; 379 line = line->next;
379 } 380 }
380 pthread_mutex_unlock(&syme->src->lock); 381 pthread_mutex_unlock(&syme->src->lock);
381 if (more) 382 if (more)
382 printf("%d lines not displayed, maybe increase display entries [e]\n", more); 383 printf("%d lines not displayed, maybe increase display entries [e]\n", more);
383 } 384 }
384 385
385 /* 386 /*
386 * Symbols will be added here in event__process_sample and will get out 387 * Symbols will be added here in event__process_sample and will get out
387 * after decayed. 388 * after decayed.
388 */ 389 */
389 static LIST_HEAD(active_symbols); 390 static LIST_HEAD(active_symbols);
390 static pthread_mutex_t active_symbols_lock = PTHREAD_MUTEX_INITIALIZER; 391 static pthread_mutex_t active_symbols_lock = PTHREAD_MUTEX_INITIALIZER;
391 392
392 /* 393 /*
393 * Ordering weight: count-1 * count-2 * ... / count-n 394 * Ordering weight: count-1 * count-2 * ... / count-n
394 */ 395 */
395 static double sym_weight(const struct sym_entry *sym) 396 static double sym_weight(const struct sym_entry *sym)
396 { 397 {
397 double weight = sym->snap_count; 398 double weight = sym->snap_count;
398 int counter; 399 int counter;
399 400
400 if (!display_weighted) 401 if (!display_weighted)
401 return weight; 402 return weight;
402 403
403 for (counter = 1; counter < nr_counters-1; counter++) 404 for (counter = 1; counter < nr_counters-1; counter++)
404 weight *= sym->count[counter]; 405 weight *= sym->count[counter];
405 406
406 weight /= (sym->count[counter] + 1); 407 weight /= (sym->count[counter] + 1);
407 408
408 return weight; 409 return weight;
409 } 410 }
410 411
411 static long samples; 412 static long samples;
412 static long userspace_samples; 413 static long userspace_samples;
413 static const char CONSOLE_CLEAR[] = ""; 414 static const char CONSOLE_CLEAR[] = "";
414 415
415 static void __list_insert_active_sym(struct sym_entry *syme) 416 static void __list_insert_active_sym(struct sym_entry *syme)
416 { 417 {
417 list_add(&syme->node, &active_symbols); 418 list_add(&syme->node, &active_symbols);
418 } 419 }
419 420
420 static void list_remove_active_sym(struct sym_entry *syme) 421 static void list_remove_active_sym(struct sym_entry *syme)
421 { 422 {
422 pthread_mutex_lock(&active_symbols_lock); 423 pthread_mutex_lock(&active_symbols_lock);
423 list_del_init(&syme->node); 424 list_del_init(&syme->node);
424 pthread_mutex_unlock(&active_symbols_lock); 425 pthread_mutex_unlock(&active_symbols_lock);
425 } 426 }
426 427
427 static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se) 428 static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)
428 { 429 {
429 struct rb_node **p = &tree->rb_node; 430 struct rb_node **p = &tree->rb_node;
430 struct rb_node *parent = NULL; 431 struct rb_node *parent = NULL;
431 struct sym_entry *iter; 432 struct sym_entry *iter;
432 433
433 while (*p != NULL) { 434 while (*p != NULL) {
434 parent = *p; 435 parent = *p;
435 iter = rb_entry(parent, struct sym_entry, rb_node); 436 iter = rb_entry(parent, struct sym_entry, rb_node);
436 437
437 if (se->weight > iter->weight) 438 if (se->weight > iter->weight)
438 p = &(*p)->rb_left; 439 p = &(*p)->rb_left;
439 else 440 else
440 p = &(*p)->rb_right; 441 p = &(*p)->rb_right;
441 } 442 }
442 443
443 rb_link_node(&se->rb_node, parent, p); 444 rb_link_node(&se->rb_node, parent, p);
444 rb_insert_color(&se->rb_node, tree); 445 rb_insert_color(&se->rb_node, tree);
445 } 446 }
446 447
447 static void print_sym_table(void) 448 static void print_sym_table(void)
448 { 449 {
449 int printed = 0, j; 450 int printed = 0, j;
450 int counter, snap = !display_weighted ? sym_counter : 0; 451 int counter, snap = !display_weighted ? sym_counter : 0;
451 float samples_per_sec = samples/delay_secs; 452 float samples_per_sec = samples/delay_secs;
452 float ksamples_per_sec = (samples-userspace_samples)/delay_secs; 453 float ksamples_per_sec = (samples-userspace_samples)/delay_secs;
453 float sum_ksamples = 0.0; 454 float sum_ksamples = 0.0;
454 struct sym_entry *syme, *n; 455 struct sym_entry *syme, *n;
455 struct rb_root tmp = RB_ROOT; 456 struct rb_root tmp = RB_ROOT;
456 struct rb_node *nd; 457 struct rb_node *nd;
457 int sym_width = 0, dso_width = 0, max_dso_width; 458 int sym_width = 0, dso_width = 0, max_dso_width;
458 const int win_width = winsize.ws_col - 1; 459 const int win_width = winsize.ws_col - 1;
459 460
460 samples = userspace_samples = 0; 461 samples = userspace_samples = 0;
461 462
462 /* Sort the active symbols */ 463 /* Sort the active symbols */
463 pthread_mutex_lock(&active_symbols_lock); 464 pthread_mutex_lock(&active_symbols_lock);
464 syme = list_entry(active_symbols.next, struct sym_entry, node); 465 syme = list_entry(active_symbols.next, struct sym_entry, node);
465 pthread_mutex_unlock(&active_symbols_lock); 466 pthread_mutex_unlock(&active_symbols_lock);
466 467
467 list_for_each_entry_safe_from(syme, n, &active_symbols, node) { 468 list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
468 syme->snap_count = syme->count[snap]; 469 syme->snap_count = syme->count[snap];
469 if (syme->snap_count != 0) { 470 if (syme->snap_count != 0) {
470 471
471 if ((hide_user_symbols && 472 if ((hide_user_symbols &&
472 syme->origin == PERF_RECORD_MISC_USER) || 473 syme->origin == PERF_RECORD_MISC_USER) ||
473 (hide_kernel_symbols && 474 (hide_kernel_symbols &&
474 syme->origin == PERF_RECORD_MISC_KERNEL)) { 475 syme->origin == PERF_RECORD_MISC_KERNEL)) {
475 list_remove_active_sym(syme); 476 list_remove_active_sym(syme);
476 continue; 477 continue;
477 } 478 }
478 syme->weight = sym_weight(syme); 479 syme->weight = sym_weight(syme);
479 rb_insert_active_sym(&tmp, syme); 480 rb_insert_active_sym(&tmp, syme);
480 sum_ksamples += syme->snap_count; 481 sum_ksamples += syme->snap_count;
481 482
482 for (j = 0; j < nr_counters; j++) 483 for (j = 0; j < nr_counters; j++)
483 syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8; 484 syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8;
484 } else 485 } else
485 list_remove_active_sym(syme); 486 list_remove_active_sym(syme);
486 } 487 }
487 488
488 puts(CONSOLE_CLEAR); 489 puts(CONSOLE_CLEAR);
489 490
490 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 491 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
491 printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% [", 492 printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% [",
492 samples_per_sec, 493 samples_per_sec,
493 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec))); 494 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)));
494 495
495 if (nr_counters == 1 || !display_weighted) { 496 if (nr_counters == 1 || !display_weighted) {
496 printf("%Ld", (u64)attrs[0].sample_period); 497 printf("%Ld", (u64)attrs[0].sample_period);
497 if (freq) 498 if (freq)
498 printf("Hz "); 499 printf("Hz ");
499 else 500 else
500 printf(" "); 501 printf(" ");
501 } 502 }
502 503
503 if (!display_weighted) 504 if (!display_weighted)
504 printf("%s", event_name(sym_counter)); 505 printf("%s", event_name(sym_counter));
505 else for (counter = 0; counter < nr_counters; counter++) { 506 else for (counter = 0; counter < nr_counters; counter++) {
506 if (counter) 507 if (counter)
507 printf("/"); 508 printf("/");
508 509
509 printf("%s", event_name(counter)); 510 printf("%s", event_name(counter));
510 } 511 }
511 512
512 printf( "], "); 513 printf( "], ");
513 514
514 if (target_pid != -1) 515 if (target_pid != -1)
515 printf(" (target_pid: %d", target_pid); 516 printf(" (target_pid: %d", target_pid);
516 else 517 else
517 printf(" (all"); 518 printf(" (all");
518 519
519 if (profile_cpu != -1) 520 if (profile_cpu != -1)
520 printf(", cpu: %d)\n", profile_cpu); 521 printf(", cpu: %d)\n", profile_cpu);
521 else { 522 else {
522 if (target_pid != -1) 523 if (target_pid != -1)
523 printf(")\n"); 524 printf(")\n");
524 else 525 else
525 printf(", %d CPUs)\n", nr_cpus); 526 printf(", %d CPUs)\n", nr_cpus);
526 } 527 }
527 528
528 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 529 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
529 530
530 if (sym_filter_entry) { 531 if (sym_filter_entry) {
531 show_details(sym_filter_entry); 532 show_details(sym_filter_entry);
532 return; 533 return;
533 } 534 }
534 535
535 /* 536 /*
536 * Find the longest symbol name that will be displayed 537 * Find the longest symbol name that will be displayed
537 */ 538 */
538 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { 539 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
539 syme = rb_entry(nd, struct sym_entry, rb_node); 540 syme = rb_entry(nd, struct sym_entry, rb_node);
540 if (++printed > print_entries || 541 if (++printed > print_entries ||
541 (int)syme->snap_count < count_filter) 542 (int)syme->snap_count < count_filter)
542 continue; 543 continue;
543 544
544 if (syme->map->dso->long_name_len > dso_width) 545 if (syme->map->dso->long_name_len > dso_width)
545 dso_width = syme->map->dso->long_name_len; 546 dso_width = syme->map->dso->long_name_len;
546 547
547 if (syme->name_len > sym_width) 548 if (syme->name_len > sym_width)
548 sym_width = syme->name_len; 549 sym_width = syme->name_len;
549 } 550 }
550 551
551 printed = 0; 552 printed = 0;
552 553
553 max_dso_width = winsize.ws_col - sym_width - 29; 554 max_dso_width = winsize.ws_col - sym_width - 29;
554 if (dso_width > max_dso_width) 555 if (dso_width > max_dso_width)
555 dso_width = max_dso_width; 556 dso_width = max_dso_width;
556 putchar('\n'); 557 putchar('\n');
557 if (nr_counters == 1) 558 if (nr_counters == 1)
558 printf(" samples pcnt"); 559 printf(" samples pcnt");
559 else 560 else
560 printf(" weight samples pcnt"); 561 printf(" weight samples pcnt");
561 562
562 if (verbose) 563 if (verbose)
563 printf(" RIP "); 564 printf(" RIP ");
564 printf(" %-*.*s DSO\n", sym_width, sym_width, "function"); 565 printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
565 printf(" %s _______ _____", 566 printf(" %s _______ _____",
566 nr_counters == 1 ? " " : "______"); 567 nr_counters == 1 ? " " : "______");
567 if (verbose) 568 if (verbose)
568 printf(" ________________"); 569 printf(" ________________");
569 printf(" %-*.*s", sym_width, sym_width, graph_line); 570 printf(" %-*.*s", sym_width, sym_width, graph_line);
570 printf(" %-*.*s", dso_width, dso_width, graph_line); 571 printf(" %-*.*s", dso_width, dso_width, graph_line);
571 puts("\n"); 572 puts("\n");
572 573
573 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { 574 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
574 struct symbol *sym; 575 struct symbol *sym;
575 double pcnt; 576 double pcnt;
576 577
577 syme = rb_entry(nd, struct sym_entry, rb_node); 578 syme = rb_entry(nd, struct sym_entry, rb_node);
578 sym = sym_entry__symbol(syme); 579 sym = sym_entry__symbol(syme);
579 580
580 if (++printed > print_entries || (int)syme->snap_count < count_filter) 581 if (++printed > print_entries || (int)syme->snap_count < count_filter)
581 continue; 582 continue;
582 583
583 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / 584 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
584 sum_ksamples)); 585 sum_ksamples));
585 586
586 if (nr_counters == 1 || !display_weighted) 587 if (nr_counters == 1 || !display_weighted)
587 printf("%20.2f ", syme->weight); 588 printf("%20.2f ", syme->weight);
588 else 589 else
589 printf("%9.1f %10ld ", syme->weight, syme->snap_count); 590 printf("%9.1f %10ld ", syme->weight, syme->snap_count);
590 591
591 percent_color_fprintf(stdout, "%4.1f%%", pcnt); 592 percent_color_fprintf(stdout, "%4.1f%%", pcnt);
592 if (verbose) 593 if (verbose)
593 printf(" %016llx", sym->start); 594 printf(" %016llx", sym->start);
594 printf(" %-*.*s", sym_width, sym_width, sym->name); 595 printf(" %-*.*s", sym_width, sym_width, sym->name);
595 printf(" %-*.*s\n", dso_width, dso_width, 596 printf(" %-*.*s\n", dso_width, dso_width,
596 dso_width >= syme->map->dso->long_name_len ? 597 dso_width >= syme->map->dso->long_name_len ?
597 syme->map->dso->long_name : 598 syme->map->dso->long_name :
598 syme->map->dso->short_name); 599 syme->map->dso->short_name);
599 } 600 }
600 } 601 }
601 602
602 static void prompt_integer(int *target, const char *msg) 603 static void prompt_integer(int *target, const char *msg)
603 { 604 {
604 char *buf = malloc(0), *p; 605 char *buf = malloc(0), *p;
605 size_t dummy = 0; 606 size_t dummy = 0;
606 int tmp; 607 int tmp;
607 608
608 fprintf(stdout, "\n%s: ", msg); 609 fprintf(stdout, "\n%s: ", msg);
609 if (getline(&buf, &dummy, stdin) < 0) 610 if (getline(&buf, &dummy, stdin) < 0)
610 return; 611 return;
611 612
612 p = strchr(buf, '\n'); 613 p = strchr(buf, '\n');
613 if (p) 614 if (p)
614 *p = 0; 615 *p = 0;
615 616
616 p = buf; 617 p = buf;
617 while(*p) { 618 while(*p) {
618 if (!isdigit(*p)) 619 if (!isdigit(*p))
619 goto out_free; 620 goto out_free;
620 p++; 621 p++;
621 } 622 }
622 tmp = strtoul(buf, NULL, 10); 623 tmp = strtoul(buf, NULL, 10);
623 *target = tmp; 624 *target = tmp;
624 out_free: 625 out_free:
625 free(buf); 626 free(buf);
626 } 627 }
627 628
628 static void prompt_percent(int *target, const char *msg) 629 static void prompt_percent(int *target, const char *msg)
629 { 630 {
630 int tmp = 0; 631 int tmp = 0;
631 632
632 prompt_integer(&tmp, msg); 633 prompt_integer(&tmp, msg);
633 if (tmp >= 0 && tmp <= 100) 634 if (tmp >= 0 && tmp <= 100)
634 *target = tmp; 635 *target = tmp;
635 } 636 }
636 637
637 static void prompt_symbol(struct sym_entry **target, const char *msg) 638 static void prompt_symbol(struct sym_entry **target, const char *msg)
638 { 639 {
639 char *buf = malloc(0), *p; 640 char *buf = malloc(0), *p;
640 struct sym_entry *syme = *target, *n, *found = NULL; 641 struct sym_entry *syme = *target, *n, *found = NULL;
641 size_t dummy = 0; 642 size_t dummy = 0;
642 643
643 /* zero counters of active symbol */ 644 /* zero counters of active symbol */
644 if (syme) { 645 if (syme) {
645 pthread_mutex_lock(&syme->src->lock); 646 pthread_mutex_lock(&syme->src->lock);
646 __zero_source_counters(syme); 647 __zero_source_counters(syme);
647 *target = NULL; 648 *target = NULL;
648 pthread_mutex_unlock(&syme->src->lock); 649 pthread_mutex_unlock(&syme->src->lock);
649 } 650 }
650 651
651 fprintf(stdout, "\n%s: ", msg); 652 fprintf(stdout, "\n%s: ", msg);
652 if (getline(&buf, &dummy, stdin) < 0) 653 if (getline(&buf, &dummy, stdin) < 0)
653 goto out_free; 654 goto out_free;
654 655
655 p = strchr(buf, '\n'); 656 p = strchr(buf, '\n');
656 if (p) 657 if (p)
657 *p = 0; 658 *p = 0;
658 659
659 pthread_mutex_lock(&active_symbols_lock); 660 pthread_mutex_lock(&active_symbols_lock);
660 syme = list_entry(active_symbols.next, struct sym_entry, node); 661 syme = list_entry(active_symbols.next, struct sym_entry, node);
661 pthread_mutex_unlock(&active_symbols_lock); 662 pthread_mutex_unlock(&active_symbols_lock);
662 663
663 list_for_each_entry_safe_from(syme, n, &active_symbols, node) { 664 list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
664 struct symbol *sym = sym_entry__symbol(syme); 665 struct symbol *sym = sym_entry__symbol(syme);
665 666
666 if (!strcmp(buf, sym->name)) { 667 if (!strcmp(buf, sym->name)) {
667 found = syme; 668 found = syme;
668 break; 669 break;
669 } 670 }
670 } 671 }
671 672
672 if (!found) { 673 if (!found) {
673 fprintf(stderr, "Sorry, %s is not active.\n", buf); 674 fprintf(stderr, "Sorry, %s is not active.\n", buf);
674 sleep(1); 675 sleep(1);
675 return; 676 return;
676 } else 677 } else
677 parse_source(found); 678 parse_source(found);
678 679
679 out_free: 680 out_free:
680 free(buf); 681 free(buf);
681 } 682 }
682 683
683 static void print_mapped_keys(void) 684 static void print_mapped_keys(void)
684 { 685 {
685 char *name = NULL; 686 char *name = NULL;
686 687
687 if (sym_filter_entry) { 688 if (sym_filter_entry) {
688 struct symbol *sym = sym_entry__symbol(sym_filter_entry); 689 struct symbol *sym = sym_entry__symbol(sym_filter_entry);
689 name = sym->name; 690 name = sym->name;
690 } 691 }
691 692
692 fprintf(stdout, "\nMapped keys:\n"); 693 fprintf(stdout, "\nMapped keys:\n");
693 fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs); 694 fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs);
694 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); 695 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries);
695 696
696 if (nr_counters > 1) 697 if (nr_counters > 1)
697 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_counter)); 698 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_counter));
698 699
699 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); 700 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter);
700 701
701 fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter); 702 fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
702 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 703 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
703 fprintf(stdout, "\t[S] stop annotation.\n"); 704 fprintf(stdout, "\t[S] stop annotation.\n");
704 705
705 if (nr_counters > 1) 706 if (nr_counters > 1)
706 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); 707 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);
707 708
708 fprintf(stdout, 709 fprintf(stdout,
709 "\t[K] hide kernel_symbols symbols. \t(%s)\n", 710 "\t[K] hide kernel_symbols symbols. \t(%s)\n",
710 hide_kernel_symbols ? "yes" : "no"); 711 hide_kernel_symbols ? "yes" : "no");
711 fprintf(stdout, 712 fprintf(stdout,
712 "\t[U] hide user symbols. \t(%s)\n", 713 "\t[U] hide user symbols. \t(%s)\n",
713 hide_user_symbols ? "yes" : "no"); 714 hide_user_symbols ? "yes" : "no");
714 fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", zero ? 1 : 0); 715 fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", zero ? 1 : 0);
715 fprintf(stdout, "\t[qQ] quit.\n"); 716 fprintf(stdout, "\t[qQ] quit.\n");
716 } 717 }
717 718
718 static int key_mapped(int c) 719 static int key_mapped(int c)
719 { 720 {
720 switch (c) { 721 switch (c) {
721 case 'd': 722 case 'd':
722 case 'e': 723 case 'e':
723 case 'f': 724 case 'f':
724 case 'z': 725 case 'z':
725 case 'q': 726 case 'q':
726 case 'Q': 727 case 'Q':
727 case 'K': 728 case 'K':
728 case 'U': 729 case 'U':
729 case 'F': 730 case 'F':
730 case 's': 731 case 's':
731 case 'S': 732 case 'S':
732 return 1; 733 return 1;
733 case 'E': 734 case 'E':
734 case 'w': 735 case 'w':
735 return nr_counters > 1 ? 1 : 0; 736 return nr_counters > 1 ? 1 : 0;
736 default: 737 default:
737 break; 738 break;
738 } 739 }
739 740
740 return 0; 741 return 0;
741 } 742 }
742 743
743 static void handle_keypress(int c) 744 static void handle_keypress(int c)
744 { 745 {
745 if (!key_mapped(c)) { 746 if (!key_mapped(c)) {
746 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 747 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
747 struct termios tc, save; 748 struct termios tc, save;
748 749
749 print_mapped_keys(); 750 print_mapped_keys();
750 fprintf(stdout, "\nEnter selection, or unmapped key to continue: "); 751 fprintf(stdout, "\nEnter selection, or unmapped key to continue: ");
751 fflush(stdout); 752 fflush(stdout);
752 753
753 tcgetattr(0, &save); 754 tcgetattr(0, &save);
754 tc = save; 755 tc = save;
755 tc.c_lflag &= ~(ICANON | ECHO); 756 tc.c_lflag &= ~(ICANON | ECHO);
756 tc.c_cc[VMIN] = 0; 757 tc.c_cc[VMIN] = 0;
757 tc.c_cc[VTIME] = 0; 758 tc.c_cc[VTIME] = 0;
758 tcsetattr(0, TCSANOW, &tc); 759 tcsetattr(0, TCSANOW, &tc);
759 760
760 poll(&stdin_poll, 1, -1); 761 poll(&stdin_poll, 1, -1);
761 c = getc(stdin); 762 c = getc(stdin);
762 763
763 tcsetattr(0, TCSAFLUSH, &save); 764 tcsetattr(0, TCSAFLUSH, &save);
764 if (!key_mapped(c)) 765 if (!key_mapped(c))
765 return; 766 return;
766 } 767 }
767 768
768 switch (c) { 769 switch (c) {
769 case 'd': 770 case 'd':
770 prompt_integer(&delay_secs, "Enter display delay"); 771 prompt_integer(&delay_secs, "Enter display delay");
771 if (delay_secs < 1) 772 if (delay_secs < 1)
772 delay_secs = 1; 773 delay_secs = 1;
773 break; 774 break;
774 case 'e': 775 case 'e':
775 prompt_integer(&print_entries, "Enter display entries (lines)"); 776 prompt_integer(&print_entries, "Enter display entries (lines)");
776 if (print_entries == 0) { 777 if (print_entries == 0) {
777 sig_winch_handler(SIGWINCH); 778 sig_winch_handler(SIGWINCH);
778 signal(SIGWINCH, sig_winch_handler); 779 signal(SIGWINCH, sig_winch_handler);
779 } else 780 } else
780 signal(SIGWINCH, SIG_DFL); 781 signal(SIGWINCH, SIG_DFL);
781 break; 782 break;
782 case 'E': 783 case 'E':
783 if (nr_counters > 1) { 784 if (nr_counters > 1) {
784 int i; 785 int i;
785 786
786 fprintf(stderr, "\nAvailable events:"); 787 fprintf(stderr, "\nAvailable events:");
787 for (i = 0; i < nr_counters; i++) 788 for (i = 0; i < nr_counters; i++)
788 fprintf(stderr, "\n\t%d %s", i, event_name(i)); 789 fprintf(stderr, "\n\t%d %s", i, event_name(i));
789 790
790 prompt_integer(&sym_counter, "Enter details event counter"); 791 prompt_integer(&sym_counter, "Enter details event counter");
791 792
792 if (sym_counter >= nr_counters) { 793 if (sym_counter >= nr_counters) {
793 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0)); 794 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0));
794 sym_counter = 0; 795 sym_counter = 0;
795 sleep(1); 796 sleep(1);
796 } 797 }
797 } else sym_counter = 0; 798 } else sym_counter = 0;
798 break; 799 break;
799 case 'f': 800 case 'f':
800 prompt_integer(&count_filter, "Enter display event count filter"); 801 prompt_integer(&count_filter, "Enter display event count filter");
801 break; 802 break;
802 case 'F': 803 case 'F':
803 prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)"); 804 prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)");
804 break; 805 break;
805 case 'K': 806 case 'K':
806 hide_kernel_symbols = !hide_kernel_symbols; 807 hide_kernel_symbols = !hide_kernel_symbols;
807 break; 808 break;
808 case 'q': 809 case 'q':
809 case 'Q': 810 case 'Q':
810 printf("exiting.\n"); 811 printf("exiting.\n");
811 if (dump_symtab) 812 if (dump_symtab)
812 dsos__fprintf(stderr); 813 dsos__fprintf(stderr);
813 exit(0); 814 exit(0);
814 case 's': 815 case 's':
815 prompt_symbol(&sym_filter_entry, "Enter details symbol"); 816 prompt_symbol(&sym_filter_entry, "Enter details symbol");
816 break; 817 break;
817 case 'S': 818 case 'S':
818 if (!sym_filter_entry) 819 if (!sym_filter_entry)
819 break; 820 break;
820 else { 821 else {
821 struct sym_entry *syme = sym_filter_entry; 822 struct sym_entry *syme = sym_filter_entry;
822 823
823 pthread_mutex_lock(&syme->src->lock); 824 pthread_mutex_lock(&syme->src->lock);
824 sym_filter_entry = NULL; 825 sym_filter_entry = NULL;
825 __zero_source_counters(syme); 826 __zero_source_counters(syme);
826 pthread_mutex_unlock(&syme->src->lock); 827 pthread_mutex_unlock(&syme->src->lock);
827 } 828 }
828 break; 829 break;
829 case 'U': 830 case 'U':
830 hide_user_symbols = !hide_user_symbols; 831 hide_user_symbols = !hide_user_symbols;
831 break; 832 break;
832 case 'w': 833 case 'w':
833 display_weighted = ~display_weighted; 834 display_weighted = ~display_weighted;
834 break; 835 break;
835 case 'z': 836 case 'z':
836 zero = ~zero; 837 zero = ~zero;
837 break; 838 break;
838 default: 839 default:
839 break; 840 break;
840 } 841 }
841 } 842 }
842 843
843 static void *display_thread(void *arg __used) 844 static void *display_thread(void *arg __used)
844 { 845 {
845 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 846 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
846 struct termios tc, save; 847 struct termios tc, save;
847 int delay_msecs, c; 848 int delay_msecs, c;
848 849
849 tcgetattr(0, &save); 850 tcgetattr(0, &save);
850 tc = save; 851 tc = save;
851 tc.c_lflag &= ~(ICANON | ECHO); 852 tc.c_lflag &= ~(ICANON | ECHO);
852 tc.c_cc[VMIN] = 0; 853 tc.c_cc[VMIN] = 0;
853 tc.c_cc[VTIME] = 0; 854 tc.c_cc[VTIME] = 0;
854 855
855 repeat: 856 repeat:
856 delay_msecs = delay_secs * 1000; 857 delay_msecs = delay_secs * 1000;
857 tcsetattr(0, TCSANOW, &tc); 858 tcsetattr(0, TCSANOW, &tc);
858 /* trash return*/ 859 /* trash return*/
859 getc(stdin); 860 getc(stdin);
860 861
861 do { 862 do {
862 print_sym_table(); 863 print_sym_table();
863 } while (!poll(&stdin_poll, 1, delay_msecs) == 1); 864 } while (!poll(&stdin_poll, 1, delay_msecs) == 1);
864 865
865 c = getc(stdin); 866 c = getc(stdin);
866 tcsetattr(0, TCSAFLUSH, &save); 867 tcsetattr(0, TCSAFLUSH, &save);
867 868
868 handle_keypress(c); 869 handle_keypress(c);
869 goto repeat; 870 goto repeat;
870 871
871 return NULL; 872 return NULL;
872 } 873 }
873 874
874 /* Tag samples to be skipped. */ 875 /* Tag samples to be skipped. */
875 static const char *skip_symbols[] = { 876 static const char *skip_symbols[] = {
876 "default_idle", 877 "default_idle",
877 "cpu_idle", 878 "cpu_idle",
878 "enter_idle", 879 "enter_idle",
879 "exit_idle", 880 "exit_idle",
880 "mwait_idle", 881 "mwait_idle",
881 "mwait_idle_with_hints", 882 "mwait_idle_with_hints",
882 "poll_idle", 883 "poll_idle",
883 "ppc64_runlatch_off", 884 "ppc64_runlatch_off",
884 "pseries_dedicated_idle_sleep", 885 "pseries_dedicated_idle_sleep",
885 NULL 886 NULL
886 }; 887 };
887 888
888 static int symbol_filter(struct map *map, struct symbol *sym) 889 static int symbol_filter(struct map *map, struct symbol *sym)
889 { 890 {
890 struct sym_entry *syme; 891 struct sym_entry *syme;
891 const char *name = sym->name; 892 const char *name = sym->name;
892 int i; 893 int i;
893 894
894 /* 895 /*
895 * ppc64 uses function descriptors and appends a '.' to the 896 * ppc64 uses function descriptors and appends a '.' to the
896 * start of every instruction address. Remove it. 897 * start of every instruction address. Remove it.
897 */ 898 */
898 if (name[0] == '.') 899 if (name[0] == '.')
899 name++; 900 name++;
900 901
901 if (!strcmp(name, "_text") || 902 if (!strcmp(name, "_text") ||
902 !strcmp(name, "_etext") || 903 !strcmp(name, "_etext") ||
903 !strcmp(name, "_sinittext") || 904 !strcmp(name, "_sinittext") ||
904 !strncmp("init_module", name, 11) || 905 !strncmp("init_module", name, 11) ||
905 !strncmp("cleanup_module", name, 14) || 906 !strncmp("cleanup_module", name, 14) ||
906 strstr(name, "_text_start") || 907 strstr(name, "_text_start") ||
907 strstr(name, "_text_end")) 908 strstr(name, "_text_end"))
908 return 1; 909 return 1;
909 910
910 syme = symbol__priv(sym); 911 syme = symbol__priv(sym);
911 syme->map = map; 912 syme->map = map;
912 syme->src = NULL; 913 syme->src = NULL;
913 914
914 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) { 915 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
915 /* schedule initial sym_filter_entry setup */ 916 /* schedule initial sym_filter_entry setup */
916 sym_filter_entry_sched = syme; 917 sym_filter_entry_sched = syme;
917 sym_filter = NULL; 918 sym_filter = NULL;
918 } 919 }
919 920
920 for (i = 0; skip_symbols[i]; i++) { 921 for (i = 0; skip_symbols[i]; i++) {
921 if (!strcmp(skip_symbols[i], name)) { 922 if (!strcmp(skip_symbols[i], name)) {
922 syme->skip = 1; 923 syme->skip = 1;
923 break; 924 break;
924 } 925 }
925 } 926 }
926 927
927 if (!syme->skip) 928 if (!syme->skip)
928 syme->name_len = strlen(sym->name); 929 syme->name_len = strlen(sym->name);
929 930
930 return 0; 931 return 0;
931 } 932 }
932 933
933 static void event__process_sample(const event_t *self, 934 static void event__process_sample(const event_t *self,
934 struct perf_session *session, int counter) 935 struct perf_session *session, int counter)
935 { 936 {
936 u64 ip = self->ip.ip; 937 u64 ip = self->ip.ip;
937 struct sym_entry *syme; 938 struct sym_entry *syme;
938 struct addr_location al; 939 struct addr_location al;
939 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 940 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
940 941
941 ++samples; 942 ++samples;
942 943
943 switch (origin) { 944 switch (origin) {
944 case PERF_RECORD_MISC_USER: 945 case PERF_RECORD_MISC_USER:
945 ++userspace_samples; 946 ++userspace_samples;
946 if (hide_user_symbols) 947 if (hide_user_symbols)
947 return; 948 return;
948 break; 949 break;
949 case PERF_RECORD_MISC_KERNEL: 950 case PERF_RECORD_MISC_KERNEL:
950 if (hide_kernel_symbols) 951 if (hide_kernel_symbols)
951 return; 952 return;
952 break; 953 break;
953 default: 954 default:
954 return; 955 return;
955 } 956 }
956 957
957 if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 || 958 if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
958 al.filtered) 959 al.filtered)
959 return; 960 return;
960 961
961 if (al.sym == NULL) { 962 if (al.sym == NULL) {
962 /* 963 /*
963 * As we do lazy loading of symtabs we only will know if the 964 * As we do lazy loading of symtabs we only will know if the
964 * specified vmlinux file is invalid when we actually have a 965 * specified vmlinux file is invalid when we actually have a
965 * hit in kernel space and then try to load it. So if we get 966 * hit in kernel space and then try to load it. So if we get
966 * here and there are _no_ symbols in the DSO backing the 967 * here and there are _no_ symbols in the DSO backing the
967 * kernel map, bail out. 968 * kernel map, bail out.
968 * 969 *
969 * We may never get here, for instance, if we use -K/ 970 * We may never get here, for instance, if we use -K/
970 * --hide-kernel-symbols, even if the user specifies an 971 * --hide-kernel-symbols, even if the user specifies an
971 * invalid --vmlinux ;-) 972 * invalid --vmlinux ;-)
972 */ 973 */
973 if (al.map == session->vmlinux_maps[MAP__FUNCTION] && 974 if (al.map == session->vmlinux_maps[MAP__FUNCTION] &&
974 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 975 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
975 pr_err("The %s file can't be used\n", 976 pr_err("The %s file can't be used\n",
976 symbol_conf.vmlinux_name); 977 symbol_conf.vmlinux_name);
977 exit(1); 978 exit(1);
978 } 979 }
979 980
980 return; 981 return;
981 } 982 }
982 983
983 /* let's see, whether we need to install initial sym_filter_entry */ 984 /* let's see, whether we need to install initial sym_filter_entry */
984 if (sym_filter_entry_sched) { 985 if (sym_filter_entry_sched) {
985 sym_filter_entry = sym_filter_entry_sched; 986 sym_filter_entry = sym_filter_entry_sched;
986 sym_filter_entry_sched = NULL; 987 sym_filter_entry_sched = NULL;
987 parse_source(sym_filter_entry); 988 parse_source(sym_filter_entry);
988 } 989 }
989 990
990 syme = symbol__priv(al.sym); 991 syme = symbol__priv(al.sym);
991 if (!syme->skip) { 992 if (!syme->skip) {
992 syme->count[counter]++; 993 syme->count[counter]++;
993 syme->origin = origin; 994 syme->origin = origin;
994 record_precise_ip(syme, counter, ip); 995 record_precise_ip(syme, counter, ip);
995 pthread_mutex_lock(&active_symbols_lock); 996 pthread_mutex_lock(&active_symbols_lock);
996 if (list_empty(&syme->node) || !syme->node.next) 997 if (list_empty(&syme->node) || !syme->node.next)
997 __list_insert_active_sym(syme); 998 __list_insert_active_sym(syme);
998 pthread_mutex_unlock(&active_symbols_lock); 999 pthread_mutex_unlock(&active_symbols_lock);
999 } 1000 }
1000 } 1001 }
1001 1002
1002 static int event__process(event_t *event, struct perf_session *session) 1003 static int event__process(event_t *event, struct perf_session *session)
1003 { 1004 {
1004 switch (event->header.type) { 1005 switch (event->header.type) {
1005 case PERF_RECORD_COMM: 1006 case PERF_RECORD_COMM:
1006 event__process_comm(event, session); 1007 event__process_comm(event, session);
1007 break; 1008 break;
1008 case PERF_RECORD_MMAP: 1009 case PERF_RECORD_MMAP:
1009 event__process_mmap(event, session); 1010 event__process_mmap(event, session);
1010 break; 1011 break;
1011 case PERF_RECORD_FORK: 1012 case PERF_RECORD_FORK:
1012 case PERF_RECORD_EXIT: 1013 case PERF_RECORD_EXIT:
1013 event__process_task(event, session); 1014 event__process_task(event, session);
1014 break; 1015 break;
1015 default: 1016 default:
1016 break; 1017 break;
1017 } 1018 }
1018 1019
1019 return 0; 1020 return 0;
1020 } 1021 }
1021 1022
1022 struct mmap_data { 1023 struct mmap_data {
1023 int counter; 1024 int counter;
1024 void *base; 1025 void *base;
1025 int mask; 1026 int mask;
1026 unsigned int prev; 1027 unsigned int prev;
1027 }; 1028 };
1028 1029
1029 static unsigned int mmap_read_head(struct mmap_data *md) 1030 static unsigned int mmap_read_head(struct mmap_data *md)
1030 { 1031 {
1031 struct perf_event_mmap_page *pc = md->base; 1032 struct perf_event_mmap_page *pc = md->base;
1032 int head; 1033 int head;
1033 1034
1034 head = pc->data_head; 1035 head = pc->data_head;
1035 rmb(); 1036 rmb();
1036 1037
1037 return head; 1038 return head;
1038 } 1039 }
1039 1040
1040 static void perf_session__mmap_read_counter(struct perf_session *self, 1041 static void perf_session__mmap_read_counter(struct perf_session *self,
1041 struct mmap_data *md) 1042 struct mmap_data *md)
1042 { 1043 {
1043 unsigned int head = mmap_read_head(md); 1044 unsigned int head = mmap_read_head(md);
1044 unsigned int old = md->prev; 1045 unsigned int old = md->prev;
1045 unsigned char *data = md->base + page_size; 1046 unsigned char *data = md->base + page_size;
1046 int diff; 1047 int diff;
1047 1048
1048 /* 1049 /*
1049 * If we're further behind than half the buffer, there's a chance 1050 * If we're further behind than half the buffer, there's a chance
1050 * the writer will bite our tail and mess up the samples under us. 1051 * the writer will bite our tail and mess up the samples under us.
1051 * 1052 *
1052 * If we somehow ended up ahead of the head, we got messed up. 1053 * If we somehow ended up ahead of the head, we got messed up.
1053 * 1054 *
1054 * In either case, truncate and restart at head. 1055 * In either case, truncate and restart at head.
1055 */ 1056 */
1056 diff = head - old; 1057 diff = head - old;
1057 if (diff > md->mask / 2 || diff < 0) { 1058 if (diff > md->mask / 2 || diff < 0) {
1058 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); 1059 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
1059 1060
1060 /* 1061 /*
1061 * head points to a known good entry, start there. 1062 * head points to a known good entry, start there.
1062 */ 1063 */
1063 old = head; 1064 old = head;
1064 } 1065 }
1065 1066
1066 for (; old != head;) { 1067 for (; old != head;) {
1067 event_t *event = (event_t *)&data[old & md->mask]; 1068 event_t *event = (event_t *)&data[old & md->mask];
1068 1069
1069 event_t event_copy; 1070 event_t event_copy;
1070 1071
1071 size_t size = event->header.size; 1072 size_t size = event->header.size;
1072 1073
1073 /* 1074 /*
1074 * Event straddles the mmap boundary -- header should always 1075 * Event straddles the mmap boundary -- header should always
1075 * be inside due to u64 alignment of output. 1076 * be inside due to u64 alignment of output.
1076 */ 1077 */
1077 if ((old & md->mask) + size != ((old + size) & md->mask)) { 1078 if ((old & md->mask) + size != ((old + size) & md->mask)) {
1078 unsigned int offset = old; 1079 unsigned int offset = old;
1079 unsigned int len = min(sizeof(*event), size), cpy; 1080 unsigned int len = min(sizeof(*event), size), cpy;
1080 void *dst = &event_copy; 1081 void *dst = &event_copy;
1081 1082
1082 do { 1083 do {
1083 cpy = min(md->mask + 1 - (offset & md->mask), len); 1084 cpy = min(md->mask + 1 - (offset & md->mask), len);
1084 memcpy(dst, &data[offset & md->mask], cpy); 1085 memcpy(dst, &data[offset & md->mask], cpy);
1085 offset += cpy; 1086 offset += cpy;
1086 dst += cpy; 1087 dst += cpy;
1087 len -= cpy; 1088 len -= cpy;
1088 } while (len); 1089 } while (len);
1089 1090
1090 event = &event_copy; 1091 event = &event_copy;
1091 } 1092 }
1092 1093
1093 if (event->header.type == PERF_RECORD_SAMPLE) 1094 if (event->header.type == PERF_RECORD_SAMPLE)
1094 event__process_sample(event, self, md->counter); 1095 event__process_sample(event, self, md->counter);
1095 else 1096 else
1096 event__process(event, self); 1097 event__process(event, self);
1097 old += size; 1098 old += size;
1098 } 1099 }
1099 1100
1100 md->prev = old; 1101 md->prev = old;
1101 } 1102 }
1102 1103
1103 static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; 1104 static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
1104 static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; 1105 static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
1105 1106
1106 static void perf_session__mmap_read(struct perf_session *self) 1107 static void perf_session__mmap_read(struct perf_session *self)
1107 { 1108 {
1108 int i, counter; 1109 int i, counter;
1109 1110
1110 for (i = 0; i < nr_cpus; i++) { 1111 for (i = 0; i < nr_cpus; i++) {
1111 for (counter = 0; counter < nr_counters; counter++) 1112 for (counter = 0; counter < nr_counters; counter++)
1112 perf_session__mmap_read_counter(self, &mmap_array[i][counter]); 1113 perf_session__mmap_read_counter(self, &mmap_array[i][counter]);
1113 } 1114 }
1114 } 1115 }
1115 1116
1116 int nr_poll; 1117 int nr_poll;
1117 int group_fd; 1118 int group_fd;
1118 1119
1119 static void start_counter(int i, int counter) 1120 static void start_counter(int i, int counter)
1120 { 1121 {
1121 struct perf_event_attr *attr; 1122 struct perf_event_attr *attr;
1122 int cpu; 1123 int cpu;
1123 1124
1124 cpu = profile_cpu; 1125 cpu = profile_cpu;
1125 if (target_pid == -1 && profile_cpu == -1) 1126 if (target_pid == -1 && profile_cpu == -1)
1126 cpu = i; 1127 cpu = cpumap[i];
1127 1128
1128 attr = attrs + counter; 1129 attr = attrs + counter;
1129 1130
1130 attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; 1131 attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
1131 1132
1132 if (freq) { 1133 if (freq) {
1133 attr->sample_type |= PERF_SAMPLE_PERIOD; 1134 attr->sample_type |= PERF_SAMPLE_PERIOD;
1134 attr->freq = 1; 1135 attr->freq = 1;
1135 attr->sample_freq = freq; 1136 attr->sample_freq = freq;
1136 } 1137 }
1137 1138
1138 attr->inherit = (cpu < 0) && inherit; 1139 attr->inherit = (cpu < 0) && inherit;
1139 attr->mmap = 1; 1140 attr->mmap = 1;
1140 1141
1141 try_again: 1142 try_again:
1142 fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0); 1143 fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
1143 1144
1144 if (fd[i][counter] < 0) { 1145 if (fd[i][counter] < 0) {
1145 int err = errno; 1146 int err = errno;
1146 1147
1147 if (err == EPERM || err == EACCES) 1148 if (err == EPERM || err == EACCES)
1148 die("No permission - are you root?\n"); 1149 die("No permission - are you root?\n");
1149 /* 1150 /*
1150 * If it's cycles then fall back to hrtimer 1151 * If it's cycles then fall back to hrtimer
1151 * based cpu-clock-tick sw counter, which 1152 * based cpu-clock-tick sw counter, which
1152 * is always available even if no PMU support: 1153 * is always available even if no PMU support:
1153 */ 1154 */
1154 if (attr->type == PERF_TYPE_HARDWARE 1155 if (attr->type == PERF_TYPE_HARDWARE
1155 && attr->config == PERF_COUNT_HW_CPU_CYCLES) { 1156 && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
1156 1157
1157 if (verbose) 1158 if (verbose)
1158 warning(" ... trying to fall back to cpu-clock-ticks\n"); 1159 warning(" ... trying to fall back to cpu-clock-ticks\n");
1159 1160
1160 attr->type = PERF_TYPE_SOFTWARE; 1161 attr->type = PERF_TYPE_SOFTWARE;
1161 attr->config = PERF_COUNT_SW_CPU_CLOCK; 1162 attr->config = PERF_COUNT_SW_CPU_CLOCK;
1162 goto try_again; 1163 goto try_again;
1163 } 1164 }
1164 printf("\n"); 1165 printf("\n");
1165 error("perfcounter syscall returned with %d (%s)\n", 1166 error("perfcounter syscall returned with %d (%s)\n",
1166 fd[i][counter], strerror(err)); 1167 fd[i][counter], strerror(err));
1167 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 1168 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
1168 exit(-1); 1169 exit(-1);
1169 } 1170 }
1170 assert(fd[i][counter] >= 0); 1171 assert(fd[i][counter] >= 0);
1171 fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); 1172 fcntl(fd[i][counter], F_SETFL, O_NONBLOCK);
1172 1173
1173 /* 1174 /*
1174 * First counter acts as the group leader: 1175 * First counter acts as the group leader:
1175 */ 1176 */
1176 if (group && group_fd == -1) 1177 if (group && group_fd == -1)
1177 group_fd = fd[i][counter]; 1178 group_fd = fd[i][counter];
1178 1179
1179 event_array[nr_poll].fd = fd[i][counter]; 1180 event_array[nr_poll].fd = fd[i][counter];
1180 event_array[nr_poll].events = POLLIN; 1181 event_array[nr_poll].events = POLLIN;
1181 nr_poll++; 1182 nr_poll++;
1182 1183
1183 mmap_array[i][counter].counter = counter; 1184 mmap_array[i][counter].counter = counter;
1184 mmap_array[i][counter].prev = 0; 1185 mmap_array[i][counter].prev = 0;
1185 mmap_array[i][counter].mask = mmap_pages*page_size - 1; 1186 mmap_array[i][counter].mask = mmap_pages*page_size - 1;
1186 mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size, 1187 mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
1187 PROT_READ, MAP_SHARED, fd[i][counter], 0); 1188 PROT_READ, MAP_SHARED, fd[i][counter], 0);
1188 if (mmap_array[i][counter].base == MAP_FAILED) 1189 if (mmap_array[i][counter].base == MAP_FAILED)
1189 die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 1190 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
1190 } 1191 }
1191 1192
1192 static int __cmd_top(void) 1193 static int __cmd_top(void)
1193 { 1194 {
1194 pthread_t thread; 1195 pthread_t thread;
1195 int i, counter; 1196 int i, counter;
1196 int ret; 1197 int ret;
1197 /* 1198 /*
1198 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 1199 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
1199 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. 1200 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
1200 */ 1201 */
1201 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false); 1202 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
1202 if (session == NULL) 1203 if (session == NULL)
1203 return -ENOMEM; 1204 return -ENOMEM;
1204 1205
1205 if (target_pid != -1) 1206 if (target_pid != -1)
1206 event__synthesize_thread(target_pid, event__process, session); 1207 event__synthesize_thread(target_pid, event__process, session);
1207 else 1208 else
1208 event__synthesize_threads(event__process, session); 1209 event__synthesize_threads(event__process, session);
1209 1210
1210 for (i = 0; i < nr_cpus; i++) { 1211 for (i = 0; i < nr_cpus; i++) {
1211 group_fd = -1; 1212 group_fd = -1;
1212 for (counter = 0; counter < nr_counters; counter++) 1213 for (counter = 0; counter < nr_counters; counter++)
1213 start_counter(i, counter); 1214 start_counter(i, counter);
1214 } 1215 }
1215 1216
1216 /* Wait for a minimal set of events before starting the snapshot */ 1217 /* Wait for a minimal set of events before starting the snapshot */
1217 poll(event_array, nr_poll, 100); 1218 poll(event_array, nr_poll, 100);
1218 1219
1219 perf_session__mmap_read(session); 1220 perf_session__mmap_read(session);
1220 1221
1221 if (pthread_create(&thread, NULL, display_thread, NULL)) { 1222 if (pthread_create(&thread, NULL, display_thread, NULL)) {
1222 printf("Could not create display thread.\n"); 1223 printf("Could not create display thread.\n");
1223 exit(-1); 1224 exit(-1);
1224 } 1225 }
1225 1226
1226 if (realtime_prio) { 1227 if (realtime_prio) {
1227 struct sched_param param; 1228 struct sched_param param;
1228 1229
1229 param.sched_priority = realtime_prio; 1230 param.sched_priority = realtime_prio;
1230 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 1231 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
1231 printf("Could not set realtime priority.\n"); 1232 printf("Could not set realtime priority.\n");
1232 exit(-1); 1233 exit(-1);
1233 } 1234 }
1234 } 1235 }
1235 1236
1236 while (1) { 1237 while (1) {
1237 int hits = samples; 1238 int hits = samples;
1238 1239
1239 perf_session__mmap_read(session); 1240 perf_session__mmap_read(session);
1240 1241
1241 if (hits == samples) 1242 if (hits == samples)
1242 ret = poll(event_array, nr_poll, 100); 1243 ret = poll(event_array, nr_poll, 100);
1243 } 1244 }
1244 1245
1245 return 0; 1246 return 0;
1246 } 1247 }
1247 1248
1248 static const char * const top_usage[] = { 1249 static const char * const top_usage[] = {
1249 "perf top [<options>]", 1250 "perf top [<options>]",
1250 NULL 1251 NULL
1251 }; 1252 };
1252 1253
1253 static const struct option options[] = { 1254 static const struct option options[] = {
1254 OPT_CALLBACK('e', "event", NULL, "event", 1255 OPT_CALLBACK('e', "event", NULL, "event",
1255 "event selector. use 'perf list' to list available events", 1256 "event selector. use 'perf list' to list available events",
1256 parse_events), 1257 parse_events),
1257 OPT_INTEGER('c', "count", &default_interval, 1258 OPT_INTEGER('c', "count", &default_interval,
1258 "event period to sample"), 1259 "event period to sample"),
1259 OPT_INTEGER('p', "pid", &target_pid, 1260 OPT_INTEGER('p', "pid", &target_pid,
1260 "profile events on existing pid"), 1261 "profile events on existing pid"),
1261 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1262 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1262 "system-wide collection from all CPUs"), 1263 "system-wide collection from all CPUs"),
1263 OPT_INTEGER('C', "CPU", &profile_cpu, 1264 OPT_INTEGER('C', "CPU", &profile_cpu,
1264 "CPU to profile on"), 1265 "CPU to profile on"),
1265 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 1266 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1266 "file", "vmlinux pathname"), 1267 "file", "vmlinux pathname"),
1267 OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols, 1268 OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
1268 "hide kernel symbols"), 1269 "hide kernel symbols"),
1269 OPT_INTEGER('m', "mmap-pages", &mmap_pages, 1270 OPT_INTEGER('m', "mmap-pages", &mmap_pages,
1270 "number of mmap data pages"), 1271 "number of mmap data pages"),
1271 OPT_INTEGER('r', "realtime", &realtime_prio, 1272 OPT_INTEGER('r', "realtime", &realtime_prio,
1272 "collect data with this RT SCHED_FIFO priority"), 1273 "collect data with this RT SCHED_FIFO priority"),
1273 OPT_INTEGER('d', "delay", &delay_secs, 1274 OPT_INTEGER('d', "delay", &delay_secs,
1274 "number of seconds to delay between refreshes"), 1275 "number of seconds to delay between refreshes"),
1275 OPT_BOOLEAN('D', "dump-symtab", &dump_symtab, 1276 OPT_BOOLEAN('D', "dump-symtab", &dump_symtab,
1276 "dump the symbol table used for profiling"), 1277 "dump the symbol table used for profiling"),
1277 OPT_INTEGER('f', "count-filter", &count_filter, 1278 OPT_INTEGER('f', "count-filter", &count_filter,
1278 "only display functions with more events than this"), 1279 "only display functions with more events than this"),
1279 OPT_BOOLEAN('g', "group", &group, 1280 OPT_BOOLEAN('g', "group", &group,
1280 "put the counters into a counter group"), 1281 "put the counters into a counter group"),
1281 OPT_BOOLEAN('i', "inherit", &inherit, 1282 OPT_BOOLEAN('i', "inherit", &inherit,
1282 "child tasks inherit counters"), 1283 "child tasks inherit counters"),
1283 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name", 1284 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
1284 "symbol to annotate"), 1285 "symbol to annotate"),
1285 OPT_BOOLEAN('z', "zero", &zero, 1286 OPT_BOOLEAN('z', "zero", &zero,
1286 "zero history across updates"), 1287 "zero history across updates"),
1287 OPT_INTEGER('F', "freq", &freq, 1288 OPT_INTEGER('F', "freq", &freq,
1288 "profile at this frequency"), 1289 "profile at this frequency"),
1289 OPT_INTEGER('E', "entries", &print_entries, 1290 OPT_INTEGER('E', "entries", &print_entries,
1290 "display this many functions"), 1291 "display this many functions"),
1291 OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols, 1292 OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
1292 "hide user symbols"), 1293 "hide user symbols"),
1293 OPT_BOOLEAN('v', "verbose", &verbose, 1294 OPT_BOOLEAN('v', "verbose", &verbose,
1294 "be more verbose (show counter open errors, etc)"), 1295 "be more verbose (show counter open errors, etc)"),
1295 OPT_END() 1296 OPT_END()
1296 }; 1297 };
1297 1298
1298 int cmd_top(int argc, const char **argv, const char *prefix __used) 1299 int cmd_top(int argc, const char **argv, const char *prefix __used)
1299 { 1300 {
1300 int counter; 1301 int counter;
1301 1302
1302 page_size = sysconf(_SC_PAGE_SIZE); 1303 page_size = sysconf(_SC_PAGE_SIZE);
1303 1304
1304 argc = parse_options(argc, argv, options, top_usage, 0); 1305 argc = parse_options(argc, argv, options, top_usage, 0);
1305 if (argc) 1306 if (argc)
1306 usage_with_options(top_usage, options); 1307 usage_with_options(top_usage, options);
1307 1308
1308 /* CPU and PID are mutually exclusive */ 1309 /* CPU and PID are mutually exclusive */
1309 if (target_pid != -1 && profile_cpu != -1) { 1310 if (target_pid != -1 && profile_cpu != -1) {
1310 printf("WARNING: PID switch overriding CPU\n"); 1311 printf("WARNING: PID switch overriding CPU\n");
1311 sleep(1); 1312 sleep(1);
1312 profile_cpu = -1; 1313 profile_cpu = -1;
1313 } 1314 }
1314 1315
1315 if (!nr_counters) 1316 if (!nr_counters)
1316 nr_counters = 1; 1317 nr_counters = 1;
1317 1318
1318 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1319 symbol_conf.priv_size = (sizeof(struct sym_entry) +
1319 (nr_counters + 1) * sizeof(unsigned long)); 1320 (nr_counters + 1) * sizeof(unsigned long));
1320 1321
1321 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 1322 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1322 if (symbol__init() < 0) 1323 if (symbol__init() < 0)
1323 return -1; 1324 return -1;
1324 1325
1325 if (delay_secs < 1) 1326 if (delay_secs < 1)
1326 delay_secs = 1; 1327 delay_secs = 1;
1327 1328
1328 /* 1329 /*
1329 * User specified count overrides default frequency. 1330 * User specified count overrides default frequency.
1330 */ 1331 */
1331 if (default_interval) 1332 if (default_interval)
1332 freq = 0; 1333 freq = 0;
1333 else if (freq) { 1334 else if (freq) {
1334 default_interval = freq; 1335 default_interval = freq;
1335 } else { 1336 } else {
1336 fprintf(stderr, "frequency and count are zero, aborting\n"); 1337 fprintf(stderr, "frequency and count are zero, aborting\n");
1337 exit(EXIT_FAILURE); 1338 exit(EXIT_FAILURE);
1338 } 1339 }
1339 1340
1340 /* 1341 /*
1341 * Fill in the ones not specifically initialized via -c: 1342 * Fill in the ones not specifically initialized via -c:
1342 */ 1343 */
1343 for (counter = 0; counter < nr_counters; counter++) { 1344 for (counter = 0; counter < nr_counters; counter++) {
1344 if (attrs[counter].sample_period) 1345 if (attrs[counter].sample_period)
1345 continue; 1346 continue;
1346 1347
1347 attrs[counter].sample_period = default_interval; 1348 attrs[counter].sample_period = default_interval;
1348 } 1349 }
1349 1350
1350 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
1351 assert(nr_cpus <= MAX_NR_CPUS);
1352 assert(nr_cpus >= 0);
1353
1354 if (target_pid != -1 || profile_cpu != -1) 1351 if (target_pid != -1 || profile_cpu != -1)
1355 nr_cpus = 1; 1352 nr_cpus = 1;
1353 else
1354 nr_cpus = read_cpu_map();
1356 1355
1357 get_term_dimensions(&winsize); 1356 get_term_dimensions(&winsize);
1358 if (print_entries == 0) { 1357 if (print_entries == 0) {
1359 update_print_entries(&winsize); 1358 update_print_entries(&winsize);
1360 signal(SIGWINCH, sig_winch_handler); 1359 signal(SIGWINCH, sig_winch_handler);
1361 } 1360 }
1362 1361
tools/perf/util/cpumap.c
File was created 1 #include "util.h"
2 #include "../perf.h"
3 #include "cpumap.h"
4 #include <assert.h>
5 #include <stdio.h>
6
7 int cpumap[MAX_NR_CPUS];
8
9 static int default_cpu_map(void)
10 {
11 int nr_cpus, i;
12
13 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
14 assert(nr_cpus <= MAX_NR_CPUS);
15 assert((int)nr_cpus >= 0);
16
17 for (i = 0; i < nr_cpus; ++i)
18 cpumap[i] = i;
19
20 return nr_cpus;
21 }
22
23 int read_cpu_map(void)
24 {
25 FILE *onlnf;
26 int nr_cpus = 0;
27 int n, cpu, prev;
28 char sep;
29
30 onlnf = fopen("/sys/devices/system/cpu/online", "r");
31 if (!onlnf)
32 return default_cpu_map();
33
34 sep = 0;
35 prev = -1;
36 for (;;) {
37 n = fscanf(onlnf, "%u%c", &cpu, &sep);
38 if (n <= 0)
39 break;
40 if (prev >= 0) {
41 assert(nr_cpus + cpu - prev - 1 < MAX_NR_CPUS);
42 while (++prev < cpu)
43 cpumap[nr_cpus++] = prev;
44 }
45 assert (nr_cpus < MAX_NR_CPUS);
46 cpumap[nr_cpus++] = cpu;
47 if (n == 2 && sep == '-')
48 prev = cpu;
49 else
50 prev = -1;
51 if (n == 1 || sep == '\n')
52 break;
53 }
54 fclose(onlnf);
55 if (nr_cpus > 0)
56 return nr_cpus;
57
58 return default_cpu_map();
59 }
60
tools/perf/util/cpumap.h
File was created 1 #ifndef __PERF_CPUMAP_H
2 #define __PERF_CPUMAP_H
3
4 extern int read_cpu_map(void);
5 extern int cpumap[];
6
7 #endif /* __PERF_CPUMAP_H */
8