Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
70a7c127
Commit
70a7c127
authored
Apr 03, 2010
by
Ingo Molnar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'perf' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6
into perf/core
parents
40b91cd1
533c46c3
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
806 additions
and
587 deletions
+806
-587
tools/perf/Makefile
tools/perf/Makefile
+168
-157
tools/perf/bench/mem-memcpy.c
tools/perf/bench/mem-memcpy.c
+0
-1
tools/perf/builtin-annotate.c
tools/perf/builtin-annotate.c
+0
-1
tools/perf/builtin-kmem.c
tools/perf/builtin-kmem.c
+7
-2
tools/perf/builtin-record.c
tools/perf/builtin-record.c
+3
-1
tools/perf/builtin-report.c
tools/perf/builtin-report.c
+14
-9
tools/perf/builtin-timechart.c
tools/perf/builtin-timechart.c
+0
-1
tools/perf/perf.c
tools/perf/perf.c
+0
-1
tools/perf/util/PERF-VERSION-GEN
tools/perf/util/PERF-VERSION-GEN
+5
-1
tools/perf/util/color.c
tools/perf/util/color.c
+49
-4
tools/perf/util/color.h
tools/perf/util/color.h
+4
-0
tools/perf/util/debug.h
tools/perf/util/debug.h
+16
-0
tools/perf/util/event.c
tools/perf/util/event.c
+9
-0
tools/perf/util/hist.c
tools/perf/util/hist.c
+45
-21
tools/perf/util/hist.h
tools/perf/util/hist.h
+7
-2
tools/perf/util/map.c
tools/perf/util/map.c
+195
-1
tools/perf/util/map.h
tools/perf/util/map.h
+28
-6
tools/perf/util/newt.c
tools/perf/util/newt.c
+167
-131
tools/perf/util/session.c
tools/perf/util/session.c
+9
-13
tools/perf/util/session.h
tools/perf/util/session.h
+15
-4
tools/perf/util/sort.c
tools/perf/util/sort.c
+48
-45
tools/perf/util/sort.h
tools/perf/util/sort.h
+3
-3
tools/perf/util/string.h
tools/perf/util/string.h
+0
-16
tools/perf/util/thread.c
tools/perf/util/thread.c
+2
-167
tools/perf/util/util.h
tools/perf/util/util.h
+12
-0
No files found.
tools/perf/Makefile
View file @
70a7c127
This diff is collapsed.
Click to expand it.
tools/perf/bench/mem-memcpy.c
View file @
70a7c127
...
...
@@ -10,7 +10,6 @@
#include "../perf.h"
#include "../util/util.h"
#include "../util/parse-options.h"
#include "../util/string.h"
#include "../util/header.h"
#include "bench.h"
...
...
tools/perf/builtin-annotate.c
View file @
70a7c127
...
...
@@ -14,7 +14,6 @@
#include "util/cache.h"
#include <linux/rbtree.h>
#include "util/symbol.h"
#include "util/string.h"
#include "perf.h"
#include "util/debug.h"
...
...
tools/perf/builtin-kmem.c
View file @
70a7c127
...
...
@@ -363,19 +363,21 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
struct
alloc_stat
*
data
=
rb_entry
(
next
,
struct
alloc_stat
,
node
);
struct
symbol
*
sym
=
NULL
;
struct
map
*
map
;
char
buf
[
BUFSIZ
];
u64
addr
;
if
(
is_caller
)
{
addr
=
data
->
call_site
;
if
(
!
raw_ip
)
sym
=
map_groups__find_function
(
&
session
->
kmaps
,
addr
,
NULL
);
sym
=
map_groups__find_function
(
&
session
->
kmaps
,
addr
,
&
map
,
NULL
);
}
else
addr
=
data
->
ptr
;
if
(
sym
!=
NULL
)
snprintf
(
buf
,
sizeof
(
buf
),
"%s+%Lx"
,
sym
->
name
,
addr
-
sym
->
start
);
addr
-
map
->
unmap_ip
(
map
,
sym
->
start
)
);
else
snprintf
(
buf
,
sizeof
(
buf
),
"%#Lx"
,
addr
);
printf
(
" %-34s |"
,
buf
);
...
...
@@ -488,6 +490,9 @@ static int __cmd_kmem(void)
if
(
session
==
NULL
)
return
-
ENOMEM
;
if
(
perf_session__create_kernel_maps
(
session
)
<
0
)
goto
out_delete
;
if
(
!
perf_session__has_traces
(
session
,
"kmem record"
))
goto
out_delete
;
...
...
tools/perf/builtin-record.c
View file @
70a7c127
...
...
@@ -15,7 +15,6 @@
#include "util/util.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
#include "util/string.h"
#include "util/header.h"
#include "util/event.h"
...
...
@@ -575,6 +574,9 @@ static int __cmd_record(int argc, const char **argv)
err
=
event__synthesize_kernel_mmap
(
process_synthesized_event
,
session
,
"_text"
);
if
(
err
<
0
)
err
=
event__synthesize_kernel_mmap
(
process_synthesized_event
,
session
,
"_stext"
);
if
(
err
<
0
)
{
pr_err
(
"Couldn't record kernel reference relocation symbol.
\n
"
);
return
err
;
...
...
tools/perf/builtin-report.c
View file @
70a7c127
...
...
@@ -14,7 +14,6 @@
#include "util/cache.h"
#include <linux/rbtree.h>
#include "util/symbol.h"
#include "util/string.h"
#include "util/callchain.h"
#include "util/strlist.h"
#include "util/values.h"
...
...
@@ -89,9 +88,12 @@ static int perf_session__add_hist_entry(struct perf_session *self,
struct
event_stat_id
*
stats
;
struct
perf_event_attr
*
attr
;
if
((
sort__has_parent
||
symbol_conf
.
use_callchain
)
&&
data
->
callchain
)
if
((
sort__has_parent
||
symbol_conf
.
use_callchain
)
&&
data
->
callchain
)
{
syms
=
perf_session__resolve_callchain
(
self
,
al
->
thread
,
data
->
callchain
,
&
parent
);
if
(
syms
==
NULL
)
return
-
ENOMEM
;
}
attr
=
perf_header__find_attr
(
data
->
id
,
&
self
->
header
);
if
(
attr
)
...
...
@@ -110,8 +112,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
if
(
symbol_conf
.
use_callchain
)
{
if
(
!
hit
)
callchain_init
(
&
he
->
callchain
);
err
=
append_chain
(
&
he
->
callchain
,
data
->
callchain
,
syms
);
callchain_init
(
he
->
callchain
);
err
=
append_chain
(
he
->
callchain
,
data
->
callchain
,
syms
);
free
(
syms
);
if
(
err
)
...
...
@@ -303,14 +305,16 @@ static int __cmd_report(void)
next
=
rb_first
(
&
session
->
stats_by_id
);
while
(
next
)
{
struct
event_stat_id
*
stats
;
u64
nr_hists
;
stats
=
rb_entry
(
next
,
struct
event_stat_id
,
rb_node
);
perf_session__collapse_resort
(
&
stats
->
hists
);
perf_session__output_resort
(
&
stats
->
hists
,
stats
->
stats
.
total
);
nr_hists
=
perf_session__output_resort
(
&
stats
->
hists
,
stats
->
stats
.
total
);
if
(
use_browser
)
perf_session__browse_hists
(
&
stats
->
hists
,
stats
->
stats
.
total
,
help
);
perf_session__browse_hists
(
&
stats
->
hists
,
nr_hists
,
stats
->
stats
.
total
,
help
,
input_name
);
else
{
if
(
rb_first
(
&
session
->
stats_by_id
)
==
rb_last
(
&
session
->
stats_by_id
))
...
...
@@ -469,7 +473,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
setup_sorting
(
report_usage
,
options
);
if
(
parent_pattern
!=
default_parent_pattern
)
{
sort_dimension__add
(
"parent"
);
if
(
sort_dimension__add
(
"parent"
)
<
0
)
return
-
1
;
sort_parent
.
elide
=
1
;
}
else
symbol_conf
.
exclude_other
=
false
;
...
...
tools/perf/builtin-timechart.c
View file @
70a7c127
...
...
@@ -21,7 +21,6 @@
#include "util/cache.h"
#include <linux/rbtree.h>
#include "util/symbol.h"
#include "util/string.h"
#include "util/callchain.h"
#include "util/strlist.h"
...
...
tools/perf/perf.c
View file @
70a7c127
...
...
@@ -13,7 +13,6 @@
#include "util/quote.h"
#include "util/run-command.h"
#include "util/parse-events.h"
#include "util/string.h"
#include "util/debugfs.h"
bool
use_browser
;
...
...
tools/perf/util/PERF-VERSION-GEN
View file @
70a7c127
#!/bin/sh
GVF
=
PERF-VERSION-FILE
if
[
$#
-eq
1
]
;
then
OUTPUT
=
$1
fi
GVF
=
${
OUTPUT
}
PERF-VERSION-FILE
DEF_VER
=
v0.0.2.PERF
LF
=
'
...
...
tools/perf/util/color.c
View file @
70a7c127
...
...
@@ -166,6 +166,31 @@ int perf_color_default_config(const char *var, const char *value, void *cb)
return
perf_default_config
(
var
,
value
,
cb
);
}
static
int
__color_vsnprintf
(
char
*
bf
,
size_t
size
,
const
char
*
color
,
const
char
*
fmt
,
va_list
args
,
const
char
*
trail
)
{
int
r
=
0
;
/*
* Auto-detect:
*/
if
(
perf_use_color_default
<
0
)
{
if
(
isatty
(
1
)
||
pager_in_use
())
perf_use_color_default
=
1
;
else
perf_use_color_default
=
0
;
}
if
(
perf_use_color_default
&&
*
color
)
r
+=
snprintf
(
bf
,
size
,
"%s"
,
color
);
r
+=
vsnprintf
(
bf
+
r
,
size
-
r
,
fmt
,
args
);
if
(
perf_use_color_default
&&
*
color
)
r
+=
snprintf
(
bf
+
r
,
size
-
r
,
"%s"
,
PERF_COLOR_RESET
);
if
(
trail
)
r
+=
snprintf
(
bf
+
r
,
size
-
r
,
"%s"
,
trail
);
return
r
;
}
static
int
__color_vfprintf
(
FILE
*
fp
,
const
char
*
color
,
const
char
*
fmt
,
va_list
args
,
const
char
*
trail
)
{
...
...
@@ -191,11 +216,28 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
return
r
;
}
int
color_vsnprintf
(
char
*
bf
,
size_t
size
,
const
char
*
color
,
const
char
*
fmt
,
va_list
args
)
{
return
__color_vsnprintf
(
bf
,
size
,
color
,
fmt
,
args
,
NULL
);
}
int
color_vfprintf
(
FILE
*
fp
,
const
char
*
color
,
const
char
*
fmt
,
va_list
args
)
{
return
__color_vfprintf
(
fp
,
color
,
fmt
,
args
,
NULL
);
}
int
color_snprintf
(
char
*
bf
,
size_t
size
,
const
char
*
color
,
const
char
*
fmt
,
...)
{
va_list
args
;
int
r
;
va_start
(
args
,
fmt
);
r
=
color_vsnprintf
(
bf
,
size
,
color
,
fmt
,
args
);
va_end
(
args
);
return
r
;
}
int
color_fprintf
(
FILE
*
fp
,
const
char
*
color
,
const
char
*
fmt
,
...)
{
...
...
@@ -203,10 +245,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
int
r
;
va_start
(
args
,
fmt
);
if
(
use_browser
)
r
=
vfprintf
(
fp
,
fmt
,
args
);
else
r
=
color_vfprintf
(
fp
,
color
,
fmt
,
args
);
r
=
color_vfprintf
(
fp
,
color
,
fmt
,
args
);
va_end
(
args
);
return
r
;
}
...
...
@@ -277,3 +316,9 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
return
r
;
}
int
percent_color_snprintf
(
char
*
bf
,
size_t
size
,
const
char
*
fmt
,
double
percent
)
{
const
char
*
color
=
get_percent_color
(
percent
);
return
color_snprintf
(
bf
,
size
,
color
,
fmt
,
percent
);
}
tools/perf/util/color.h
View file @
70a7c127
...
...
@@ -32,10 +32,14 @@ int perf_color_default_config(const char *var, const char *value, void *cb);
int
perf_config_colorbool
(
const
char
*
var
,
const
char
*
value
,
int
stdout_is_tty
);
void
color_parse
(
const
char
*
value
,
const
char
*
var
,
char
*
dst
);
void
color_parse_mem
(
const
char
*
value
,
int
len
,
const
char
*
var
,
char
*
dst
);
int
color_vsnprintf
(
char
*
bf
,
size_t
size
,
const
char
*
color
,
const
char
*
fmt
,
va_list
args
);
int
color_vfprintf
(
FILE
*
fp
,
const
char
*
color
,
const
char
*
fmt
,
va_list
args
);
int
color_fprintf
(
FILE
*
fp
,
const
char
*
color
,
const
char
*
fmt
,
...);
int
color_snprintf
(
char
*
bf
,
size_t
size
,
const
char
*
color
,
const
char
*
fmt
,
...);
int
color_fprintf_ln
(
FILE
*
fp
,
const
char
*
color
,
const
char
*
fmt
,
...);
int
color_fwrite_lines
(
FILE
*
fp
,
const
char
*
color
,
size_t
count
,
const
char
*
buf
);
int
percent_color_snprintf
(
char
*
bf
,
size_t
size
,
const
char
*
fmt
,
double
percent
);
int
percent_color_fprintf
(
FILE
*
fp
,
const
char
*
fmt
,
double
percent
);
const
char
*
get_percent_color
(
double
percent
);
...
...
tools/perf/util/debug.h
View file @
70a7c127
...
...
@@ -10,13 +10,29 @@ extern int dump_trace;
int
dump_printf
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
trace_event
(
event_t
*
event
);
struct
ui_progress
;
#ifdef NO_NEWT_SUPPORT
static
inline
int
browser__show_help
(
const
char
*
format
__used
,
va_list
ap
__used
)
{
return
0
;
}
static
inline
struct
ui_progress
*
ui_progress__new
(
const
char
*
title
__used
,
u64
total
__used
)
{
return
(
struct
ui_progress
*
)
1
;
}
static
inline
void
ui_progress__update
(
struct
ui_progress
*
self
__used
,
u64
curr
__used
)
{}
static
inline
void
ui_progress__delete
(
struct
ui_progress
*
self
__used
)
{}
#else
int
browser__show_help
(
const
char
*
format
,
va_list
ap
);
struct
ui_progress
*
ui_progress__new
(
const
char
*
title
,
u64
total
);
void
ui_progress__update
(
struct
ui_progress
*
self
,
u64
curr
);
void
ui_progress__delete
(
struct
ui_progress
*
self
);
#endif
#endif
/* __PERF_DEBUG_H */
tools/perf/util/event.c
View file @
70a7c127
...
...
@@ -130,6 +130,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
continue
;
pbf
+=
n
+
3
;
if
(
*
pbf
==
'x'
)
{
/* vm_exec */
u64
vm_pgoff
;
char
*
execname
=
strchr
(
bf
,
'/'
);
/* Catch VDSO */
...
...
@@ -139,6 +140,14 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
if
(
execname
==
NULL
)
continue
;
pbf
+=
3
;
n
=
hex2u64
(
pbf
,
&
vm_pgoff
);
/* pgoff is in bytes, not pages */
if
(
n
>=
0
)
ev
.
mmap
.
pgoff
=
vm_pgoff
<<
getpagesize
();
else
ev
.
mmap
.
pgoff
=
0
;
size
=
strlen
(
execname
);
execname
[
size
-
1
]
=
'\0'
;
/* Remove \n */
memcpy
(
ev
.
mmap
.
filename
,
execname
,
size
);
...
...
tools/perf/util/hist.c
View file @
70a7c127
...
...
@@ -50,7 +50,8 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
p
=
&
(
*
p
)
->
rb_right
;
}
he
=
malloc
(
sizeof
(
*
he
));
he
=
malloc
(
sizeof
(
*
he
)
+
(
symbol_conf
.
use_callchain
?
sizeof
(
struct
callchain_node
)
:
0
));
if
(
!
he
)
return
NULL
;
*
he
=
entry
;
...
...
@@ -168,7 +169,7 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
struct
hist_entry
*
iter
;
if
(
symbol_conf
.
use_callchain
)
callchain_param
.
sort
(
&
he
->
sorted_chain
,
&
he
->
callchain
,
callchain_param
.
sort
(
&
he
->
sorted_chain
,
he
->
callchain
,
min_callchain_hits
,
&
callchain_param
);
while
(
*
p
!=
NULL
)
{
...
...
@@ -185,12 +186,13 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
rb_insert_color
(
&
he
->
rb_node
,
root
);
}
void
perf_session__output_resort
(
struct
rb_root
*
hists
,
u64
total_samples
)
u64
perf_session__output_resort
(
struct
rb_root
*
hists
,
u64
total_samples
)
{
struct
rb_root
tmp
;
struct
rb_node
*
next
;
struct
hist_entry
*
n
;
u64
min_callchain_hits
;
u64
nr_hists
=
0
;
min_callchain_hits
=
total_samples
*
(
callchain_param
.
min_percent
/
100
);
...
...
@@ -205,9 +207,11 @@ void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
rb_erase
(
&
n
->
rb_node
,
hists
);
perf_session__insert_output_hist_entry
(
&
tmp
,
n
,
min_callchain_hits
);
++
nr_hists
;
}
*
hists
=
tmp
;
return
nr_hists
;
}
static
size_t
callchain__fprintf_left_margin
(
FILE
*
fp
,
int
left_margin
)
...
...
@@ -452,16 +456,17 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
return
ret
;
}
size_t
hist_entry__fprintf
(
struct
hist_entry
*
self
,
int
hist_entry__snprintf
(
struct
hist_entry
*
self
,
char
*
s
,
size_t
size
,
struct
perf_session
*
pair_session
,
bool
show_displacement
,
long
displacement
,
FILE
*
fp
,
long
displacement
,
bool
color
,
u64
session_total
)
{
struct
sort_entry
*
se
;
u64
count
,
total
;
const
char
*
sep
=
symbol_conf
.
field_sep
;
size_
t
ret
;
in
t
ret
;
if
(
symbol_conf
.
exclude_other
&&
!
self
->
parent
)
return
0
;
...
...
@@ -474,17 +479,22 @@ size_t hist_entry__fprintf(struct hist_entry *self,
total
=
session_total
;
}
if
(
total
)
ret
=
percent_color_fprintf
(
fp
,
sep
?
"%.2f"
:
" %6.2f%%"
,
(
count
*
100
.
0
)
/
total
);
else
ret
=
fprintf
(
fp
,
sep
?
"%lld"
:
"%12lld "
,
count
);
if
(
total
)
{
if
(
color
)
ret
=
percent_color_snprintf
(
s
,
size
,
sep
?
"%.2f"
:
" %6.2f%%"
,
(
count
*
100
.
0
)
/
total
);
else
ret
=
snprintf
(
s
,
size
,
sep
?
"%.2f"
:
" %6.2f%%"
,
(
count
*
100
.
0
)
/
total
);
}
else
ret
=
snprintf
(
s
,
size
,
sep
?
"%lld"
:
"%12lld "
,
count
);
if
(
symbol_conf
.
show_nr_samples
)
{
if
(
sep
)
ret
+=
fprintf
(
fp
,
"%c%lld"
,
*
sep
,
count
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%c%lld"
,
*
sep
,
count
);
else
ret
+=
fprintf
(
fp
,
"%11lld"
,
count
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%11lld"
,
count
);
}
if
(
pair_session
)
{
...
...
@@ -504,9 +514,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
snprintf
(
bf
,
sizeof
(
bf
),
" "
);
if
(
sep
)
ret
+=
fprintf
(
fp
,
"%c%s"
,
*
sep
,
bf
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%c%s"
,
*
sep
,
bf
);
else
ret
+=
fprintf
(
fp
,
"%11.11s"
,
bf
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%11.11s"
,
bf
);
if
(
show_displacement
)
{
if
(
displacement
)
...
...
@@ -515,9 +525,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
snprintf
(
bf
,
sizeof
(
bf
),
" "
);
if
(
sep
)
ret
+=
fprintf
(
fp
,
"%c%s"
,
*
sep
,
bf
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%c%s"
,
*
sep
,
bf
);
else
ret
+=
fprintf
(
fp
,
"%6.6s"
,
bf
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%6.6s"
,
bf
);
}
}
...
...
@@ -525,11 +535,25 @@ size_t hist_entry__fprintf(struct hist_entry *self,
if
(
se
->
elide
)
continue
;
ret
+=
fprintf
(
fp
,
"%s"
,
sep
?:
" "
);
ret
+=
se
->
print
(
fp
,
self
,
se
->
width
?
*
se
->
width
:
0
);
ret
+=
snprintf
(
s
+
ret
,
size
-
ret
,
"%s"
,
sep
?:
" "
);
ret
+=
se
->
snprintf
(
self
,
s
+
ret
,
size
-
ret
,
se
->
width
?
*
se
->
width
:
0
);
}
return
ret
+
fprintf
(
fp
,
"
\n
"
);
return
ret
;
}
int
hist_entry__fprintf
(
struct
hist_entry
*
self
,
struct
perf_session
*
pair_session
,
bool
show_displacement
,
long
displacement
,
FILE
*
fp
,
u64
session_total
)
{
char
bf
[
512
];
hist_entry__snprintf
(
self
,
bf
,
sizeof
(
bf
),
pair_session
,
show_displacement
,
displacement
,
true
,
session_total
);
return
fprintf
(
fp
,
"%s
\n
"
,
bf
);
}
static
size_t
hist_entry__fprintf_callchain
(
struct
hist_entry
*
self
,
FILE
*
fp
,
...
...
@@ -658,7 +682,7 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
if
(
h
->
ms
.
map
==
NULL
&&
verbose
>
1
)
{
__map_groups__fprintf_maps
(
&
h
->
thread
->
mg
,
MAP__FUNCTION
,
fp
);
MAP__FUNCTION
,
verbose
,
fp
);
fprintf
(
fp
,
"%.10s end
\n
"
,
graph_dotted_line
);
}
}
...
...
tools/perf/util/hist.h
View file @
70a7c127
...
...
@@ -18,14 +18,19 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
u64
count
,
bool
*
hit
);
extern
int64_t
hist_entry__cmp
(
struct
hist_entry
*
,
struct
hist_entry
*
);
extern
int64_t
hist_entry__collapse
(
struct
hist_entry
*
,
struct
hist_entry
*
);
size_
t
hist_entry__fprintf
(
struct
hist_entry
*
self
,
in
t
hist_entry__fprintf
(
struct
hist_entry
*
self
,
struct
perf_session
*
pair_session
,
bool
show_displacement
,
long
displacement
,
FILE
*
fp
,
u64
session_total
);
int
hist_entry__snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
struct
perf_session
*
pair_session
,
bool
show_displacement
,
long
displacement
,
bool
color
,
u64
session_total
);
void
hist_entry__free
(
struct
hist_entry
*
);
void
perf_session__output_resort
(
struct
rb_root
*
hists
,
u64
total_samples
);
u64
perf_session__output_resort
(
struct
rb_root
*
hists
,
u64
total_samples
);
void
perf_session__collapse_resort
(
struct
rb_root
*
hists
);
size_t
perf_session__fprintf_hists
(
struct
rb_root
*
hists
,
struct
perf_session
*
pair
,
...
...
tools/perf/util/map.c
View file @
70a7c127
#include "symbol.h"
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -234,18 +235,211 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
return
ip
;
}
void
map_groups__init
(
struct
map_groups
*
self
)
{
int
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
{
self
->
maps
[
i
]
=
RB_ROOT
;
INIT_LIST_HEAD
(
&
self
->
removed_maps
[
i
]);
}
}
void
map_groups__flush
(
struct
map_groups
*
self
)
{
int
type
;
for
(
type
=
0
;
type
<
MAP__NR_TYPES
;
type
++
)
{
struct
rb_root
*
root
=
&
self
->
maps
[
type
];
struct
rb_node
*
next
=
rb_first
(
root
);
while
(
next
)
{
struct
map
*
pos
=
rb_entry
(
next
,
struct
map
,
rb_node
);
next
=
rb_next
(
&
pos
->
rb_node
);
rb_erase
(
&
pos
->
rb_node
,
root
);
/*
* We may have references to this map, for
* instance in some hist_entry instances, so
* just move them to a separate list.
*/
list_add_tail
(
&
pos
->
node
,
&
self
->
removed_maps
[
pos
->
type
]);
}
}
}
struct
symbol
*
map_groups__find_symbol
(
struct
map_groups
*
self
,
enum
map_type
type
,
u64
addr
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
{
struct
map
*
map
=
map_groups__find
(
self
,
type
,
addr
);
if
(
map
!=
NULL
)
if
(
map
!=
NULL
)
{
if
(
mapp
!=
NULL
)
*
mapp
=
map
;
return
map__find_symbol
(
map
,
map
->
map_ip
(
map
,
addr
),
filter
);
}
return
NULL
;
}
struct
symbol
*
map_groups__find_symbol_by_name
(
struct
map_groups
*
self
,
enum
map_type
type
,
const
char
*
name
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
{
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
&
self
->
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
pos
=
rb_entry
(
nd
,
struct
map
,
rb_node
);
struct
symbol
*
sym
=
map__find_symbol_by_name
(
pos
,
name
,
filter
);
if
(
sym
==
NULL
)
continue
;
if
(
mapp
!=
NULL
)
*
mapp
=
pos
;
return
sym
;
}
return
NULL
;
}
size_t
__map_groups__fprintf_maps
(
struct
map_groups
*
self
,
enum
map_type
type
,
int
verbose
,
FILE
*
fp
)
{
size_t
printed
=
fprintf
(
fp
,
"%s:
\n
"
,
map_type__name
[
type
]);
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
&
self
->
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
pos
=
rb_entry
(
nd
,
struct
map
,
rb_node
);
printed
+=
fprintf
(
fp
,
"Map:"
);
printed
+=
map__fprintf
(
pos
,
fp
);
if
(
verbose
>
2
)
{
printed
+=
dso__fprintf
(
pos
->
dso
,
type
,
fp
);
printed
+=
fprintf
(
fp
,
"--
\n
"
);
}
}
return
printed
;
}
size_t
map_groups__fprintf_maps
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
)
{
size_t
printed
=
0
,
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
printed
+=
__map_groups__fprintf_maps
(
self
,
i
,
verbose
,
fp
);
return
printed
;
}
static
size_t
__map_groups__fprintf_removed_maps
(
struct
map_groups
*
self
,
enum
map_type
type
,
int
verbose
,
FILE
*
fp
)
{
struct
map
*
pos
;
size_t
printed
=
0
;
list_for_each_entry
(
pos
,
&
self
->
removed_maps
[
type
],
node
)
{
printed
+=
fprintf
(
fp
,
"Map:"
);
printed
+=
map__fprintf
(
pos
,
fp
);
if
(
verbose
>
1
)
{
printed
+=
dso__fprintf
(
pos
->
dso
,
type
,
fp
);
printed
+=
fprintf
(
fp
,
"--
\n
"
);
}
}
return
printed
;
}
static
size_t
map_groups__fprintf_removed_maps
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
)
{
size_t
printed
=
0
,
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
printed
+=
__map_groups__fprintf_removed_maps
(
self
,
i
,
verbose
,
fp
);
return
printed
;
}
size_t
map_groups__fprintf
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
)
{
size_t
printed
=
map_groups__fprintf_maps
(
self
,
verbose
,
fp
);
printed
+=
fprintf
(
fp
,
"Removed maps:
\n
"
);
return
printed
+
map_groups__fprintf_removed_maps
(
self
,
verbose
,
fp
);
}
int
map_groups__fixup_overlappings
(
struct
map_groups
*
self
,
struct
map
*
map
,
int
verbose
,
FILE
*
fp
)
{
struct
rb_root
*
root
=
&
self
->
maps
[
map
->
type
];
struct
rb_node
*
next
=
rb_first
(
root
);
while
(
next
)
{
struct
map
*
pos
=
rb_entry
(
next
,
struct
map
,
rb_node
);
next
=
rb_next
(
&
pos
->
rb_node
);
if
(
!
map__overlap
(
pos
,
map
))
continue
;
if
(
verbose
>=
2
)
{
fputs
(
"overlapping maps:
\n
"
,
fp
);
map__fprintf
(
map
,
fp
);
map__fprintf
(
pos
,
fp
);
}
rb_erase
(
&
pos
->
rb_node
,
root
);
/*
* We may have references to this map, for instance in some
* hist_entry instances, so just move them to a separate
* list.
*/
list_add_tail
(
&
pos
->
node
,
&
self
->
removed_maps
[
map
->
type
]);
/*
* Now check if we need to create new maps for areas not
* overlapped by the new map:
*/
if
(
map
->
start
>
pos
->
start
)
{
struct
map
*
before
=
map__clone
(
pos
);
if
(
before
==
NULL
)
return
-
ENOMEM
;
before
->
end
=
map
->
start
-
1
;
map_groups__insert
(
self
,
before
);
if
(
verbose
>=
2
)
map__fprintf
(
before
,
fp
);
}
if
(
map
->
end
<
pos
->
end
)
{
struct
map
*
after
=
map__clone
(
pos
);
if
(
after
==
NULL
)
return
-
ENOMEM
;
after
->
start
=
map
->
end
+
1
;
map_groups__insert
(
self
,
after
);
if
(
verbose
>=
2
)
map__fprintf
(
after
,
fp
);
}
}
return
0
;
}
/*
* XXX This should not really _copy_ te maps, but refcount them.
*/
int
map_groups__clone
(
struct
map_groups
*
self
,
struct
map_groups
*
parent
,
enum
map_type
type
)
{
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
&
parent
->
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
map
=
rb_entry
(
nd
,
struct
map
,
rb_node
);
struct
map
*
new
=
map__clone
(
map
);
if
(
new
==
NULL
)
return
-
ENOMEM
;
map_groups__insert
(
self
,
new
);
}
return
0
;
}
static
u64
map__reloc_map_ip
(
struct
map
*
map
,
u64
ip
)
{
return
ip
+
(
s64
)
map
->
pgoff
;
...
...
tools/perf/util/map.h
View file @
70a7c127
...
...
@@ -97,11 +97,14 @@ struct map_groups {
};
size_t
__map_groups__fprintf_maps
(
struct
map_groups
*
self
,
enum
map_type
type
,
FILE
*
fp
);
enum
map_type
type
,
int
verbose
,
FILE
*
fp
);
void
maps__insert
(
struct
rb_root
*
maps
,
struct
map
*
map
);
struct
map
*
maps__find
(
struct
rb_root
*
maps
,
u64
addr
);
void
map_groups__init
(
struct
map_groups
*
self
);
size_t
map_groups__fprintf_maps
(
struct
map_groups
*
self
,
FILE
*
fp
);
int
map_groups__clone
(
struct
map_groups
*
self
,
struct
map_groups
*
parent
,
enum
map_type
type
);
size_t
map_groups__fprintf
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
);
size_t
map_groups__fprintf_maps
(
struct
map_groups
*
self
,
int
verbose
,
FILE
*
fp
);
static
inline
void
map_groups__insert
(
struct
map_groups
*
self
,
struct
map
*
map
)
{
...
...
@@ -116,15 +119,33 @@ static inline struct map *map_groups__find(struct map_groups *self,
struct
symbol
*
map_groups__find_symbol
(
struct
map_groups
*
self
,
enum
map_type
type
,
u64
addr
,
struct
map
**
mapp
,
symbol_filter_t
filter
);
static
inline
struct
symbol
*
map_groups__find_function
(
struct
map_groups
*
self
,
u64
addr
,
symbol_filter_t
filter
)
struct
symbol
*
map_groups__find_symbol_by_name
(
struct
map_groups
*
self
,
enum
map_type
type
,
const
char
*
name
,
struct
map
**
mapp
,
symbol_filter_t
filter
);
static
inline
struct
symbol
*
map_groups__find_function
(
struct
map_groups
*
self
,
u64
addr
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
{
return
map_groups__find_symbol
(
self
,
MAP__FUNCTION
,
addr
,
filter
);
return
map_groups__find_symbol
(
self
,
MAP__FUNCTION
,
addr
,
mapp
,
filter
);
}
static
inline
struct
symbol
*
map_groups__find_function_by_name
(
struct
map_groups
*
self
,
const
char
*
name
,
struct
map
**
mapp
,
symbol_filter_t
filter
)
{
return
map_groups__find_symbol_by_name
(
self
,
MAP__FUNCTION
,
name
,
mapp
,
filter
);
}
int
map_groups__fixup_overlappings
(
struct
map_groups
*
self
,
struct
map
*
map
,
int
verbose
,
FILE
*
fp
);
struct
map
*
map_groups__find_by_name
(
struct
map_groups
*
self
,
enum
map_type
type
,
const
char
*
name
);
int
__map_groups__create_kernel_maps
(
struct
map_groups
*
self
,
...
...
@@ -134,5 +155,6 @@ int map_groups__create_kernel_maps(struct map_groups *self,
struct
map
*
vmlinux_maps
[
MAP__NR_TYPES
]);
struct
map
*
map_groups__new_module
(
struct
map_groups
*
self
,
u64
start
,
const
char
*
filename
);
void
map_groups__flush
(
struct
map_groups
*
self
);
#endif
/* __PERF_MAP_H */
tools/perf/util/newt.c
View file @
70a7c127
This diff is collapsed.
Click to expand it.
tools/perf/util/session.c
View file @
70a7c127
...
...
@@ -52,11 +52,6 @@ static int perf_session__open(struct perf_session *self, bool force)
return
-
1
;
}
static
inline
int
perf_session__create_kernel_maps
(
struct
perf_session
*
self
)
{
return
map_groups__create_kernel_maps
(
&
self
->
kmaps
,
self
->
vmlinux_maps
);
}
struct
perf_session
*
perf_session__new
(
const
char
*
filename
,
int
mode
,
bool
force
)
{
size_t
len
=
filename
?
strlen
(
filename
)
+
1
:
0
;
...
...
@@ -123,16 +118,11 @@ struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
struct
symbol
**
parent
)
{
u8
cpumode
=
PERF_RECORD_MISC_USER
;
struct
map_symbol
*
syms
=
NULL
;
unsigned
int
i
;
struct
map_symbol
*
syms
=
calloc
(
chain
->
nr
,
sizeof
(
*
syms
));
if
(
symbol_conf
.
use_callchain
)
{
syms
=
calloc
(
chain
->
nr
,
sizeof
(
*
syms
));
if
(
!
syms
)
{
fprintf
(
stderr
,
"Can't allocate memory for symbols
\n
"
);
exit
(
-
1
);
}
}
if
(
!
syms
)
return
NULL
;
for
(
i
=
0
;
i
<
chain
->
nr
;
i
++
)
{
u64
ip
=
chain
->
ips
[
i
];
...
...
@@ -397,6 +387,10 @@ int __perf_session__process_events(struct perf_session *self,
event_t
*
event
;
uint32_t
size
;
char
*
buf
;
struct
ui_progress
*
progress
=
ui_progress__new
(
"Processing events..."
,
self
->
size
);
if
(
progress
==
NULL
)
return
-
1
;
perf_event_ops__fill_defaults
(
ops
);
...
...
@@ -425,6 +419,7 @@ int __perf_session__process_events(struct perf_session *self,
more:
event
=
(
event_t
*
)(
buf
+
head
);
ui_progress__update
(
progress
,
offset
);
if
(
self
->
header
.
needs_swap
)
perf_event_header__bswap
(
&
event
->
header
);
...
...
@@ -475,6 +470,7 @@ int __perf_session__process_events(struct perf_session *self,
done:
err
=
0
;
out_err:
ui_progress__delete
(
progress
);
return
err
;
}
...
...
tools/perf/util/session.h
View file @
70a7c127
...
...
@@ -80,6 +80,11 @@ static inline int __perf_session__create_kernel_maps(struct perf_session *self,
self
->
vmlinux_maps
,
kernel
);
}
static
inline
int
perf_session__create_kernel_maps
(
struct
perf_session
*
self
)
{
return
map_groups__create_kernel_maps
(
&
self
->
kmaps
,
self
->
vmlinux_maps
);
}
static
inline
struct
map
*
perf_session__new_module_map
(
struct
perf_session
*
self
,
u64
start
,
const
char
*
filename
)
...
...
@@ -88,11 +93,17 @@ static inline struct map *
}
#ifdef NO_NEWT_SUPPORT
static
inline
void
perf_session__browse_hists
(
struct
rb_root
*
hists
__used
,
static
inline
int
perf_session__browse_hists
(
struct
rb_root
*
hists
__used
,
u64
nr_hists
__used
,
u64
session_total
__used
,
const
char
*
helpline
__used
)
{}
const
char
*
helpline
__used
,
const
char
*
input_name
__used
)
{
return
0
;
}
#else
void
perf_session__browse_hists
(
struct
rb_root
*
hists
,
u64
session_total
,
const
char
*
helpline
);
int
perf_session__browse_hists
(
struct
rb_root
*
hists
,
u64
nr_hists
,
u64
session_total
,
const
char
*
helpline
,
const
char
*
input_name
);
#endif
#endif
/* __PERF_SESSION_H */
tools/perf/util/sort.c
View file @
70a7c127
...
...
@@ -18,10 +18,21 @@ char * field_sep;
LIST_HEAD
(
hist_entry__sort_list
);
static
int
hist_entry__thread_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
);
static
int
hist_entry__comm_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
);
static
int
hist_entry__dso_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
);
static
int
hist_entry__sym_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
);
static
int
hist_entry__parent_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
);
struct
sort_entry
sort_thread
=
{
.
header
=
"Command: Pid"
,
.
cmp
=
sort__thread_cmp
,
.
print
=
sort__thread_print
,
.
snprintf
=
hist_entry__thread_snprintf
,
.
width
=
&
threads__col_width
,
};
...
...
@@ -29,27 +40,27 @@ struct sort_entry sort_comm = {
.
header
=
"Command"
,
.
cmp
=
sort__comm_cmp
,
.
collapse
=
sort__comm_collapse
,
.
print
=
sort__comm_print
,
.
snprintf
=
hist_entry__comm_snprintf
,
.
width
=
&
comms__col_width
,
};
struct
sort_entry
sort_dso
=
{
.
header
=
"Shared Object"
,
.
cmp
=
sort__dso_cmp
,
.
print
=
sort__dso_print
,
.
snprintf
=
hist_entry__dso_snprintf
,
.
width
=
&
dsos__col_width
,
};
struct
sort_entry
sort_sym
=
{
.
header
=
"Symbol"
,
.
cmp
=
sort__sym_cmp
,
.
print
=
sort__sym_print
,
.
snprintf
=
hist_entry__sym_snprintf
,
};
struct
sort_entry
sort_parent
=
{
.
header
=
"Parent symbol"
,
.
cmp
=
sort__parent_cmp
,
.
print
=
sort__parent_print
,
.
snprintf
=
hist_entry__parent_snprintf
,
.
width
=
&
parent_symbol__col_width
,
};
...
...
@@ -85,45 +96,38 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
return
right
->
thread
->
pid
-
left
->
thread
->
pid
;
}
int
repsep_fprintf
(
FILE
*
fp
,
const
char
*
fmt
,
...)
static
int
repsep_snprintf
(
char
*
bf
,
size_t
size
,
const
char
*
fmt
,
...)
{
int
n
;
va_list
ap
;
va_start
(
ap
,
fmt
);
if
(
!
field_sep
)
n
=
vfprintf
(
fp
,
fmt
,
ap
);
else
{
char
*
bf
=
NULL
;
n
=
vasprintf
(
&
bf
,
fmt
,
ap
);
if
(
n
>
0
)
{
char
*
sep
=
bf
;
while
(
1
)
{
sep
=
strchr
(
sep
,
*
field_sep
);
if
(
sep
==
NULL
)
break
;
*
sep
=
'.'
;
}
n
=
vsnprintf
(
bf
,
size
,
fmt
,
ap
);
if
(
field_sep
&&
n
>
0
)
{
char
*
sep
=
bf
;
while
(
1
)
{
sep
=
strchr
(
sep
,
*
field_sep
);
if
(
sep
==
NULL
)
break
;
*
sep
=
'.'
;
}
fputs
(
bf
,
fp
);
free
(
bf
);
}
va_end
(
ap
);
return
n
;
}
s
ize_t
sort__thread_print
(
FILE
*
fp
,
struct
hist_entry
*
self
,
unsigned
int
width
)
s
tatic
int
hist_entry__thread_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
)
{
return
repsep_
fprintf
(
fp
,
"%*s:%5d"
,
width
-
6
,
return
repsep_
snprintf
(
bf
,
size
,
"%*s:%5d"
,
width
,
self
->
thread
->
comm
?:
""
,
self
->
thread
->
pid
);
}
s
ize_t
sort__comm_print
(
FILE
*
fp
,
struct
hist_entry
*
self
,
unsigned
int
width
)
s
tatic
int
hist_entry__comm_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
)
{
return
repsep_
fprintf
(
fp
,
"%*s"
,
width
,
self
->
thread
->
comm
);
return
repsep_
snprintf
(
bf
,
size
,
"%*s"
,
width
,
self
->
thread
->
comm
);
}
/* --sort dso */
...
...
@@ -149,16 +153,16 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
return
strcmp
(
dso_name_l
,
dso_name_r
);
}
s
ize_t
sort__dso_print
(
FILE
*
fp
,
struct
hist_entry
*
self
,
unsigned
int
width
)
s
tatic
int
hist_entry__dso_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
)
{
if
(
self
->
ms
.
map
&&
self
->
ms
.
map
->
dso
)
{
const
char
*
dso_name
=
!
verbose
?
self
->
ms
.
map
->
dso
->
short_name
:
self
->
ms
.
map
->
dso
->
long_name
;
return
repsep_
fprintf
(
fp
,
"%-*s"
,
width
,
dso_name
);
return
repsep_
snprintf
(
bf
,
size
,
"%-*s"
,
width
,
dso_name
);
}
return
repsep_
fprintf
(
fp
,
"%*llx"
,
width
,
(
u64
)
self
->
ip
);
return
repsep_
snprintf
(
bf
,
size
,
"%*Lx"
,
width
,
self
->
ip
);
}
/* --sort symbol */
...
...
@@ -177,22 +181,22 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
return
(
int64_t
)(
ip_r
-
ip_l
);
}
size_t
sort__sym_print
(
FILE
*
fp
,
struct
hist_entry
*
self
,
unsigned
int
width
__used
)
static
int
hist_entry__sym_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
__used
)
{
size_t
ret
=
0
;
if
(
verbose
)
{
char
o
=
self
->
ms
.
map
?
dso__symtab_origin
(
self
->
ms
.
map
->
dso
)
:
'!'
;
ret
+=
repsep_
fprintf
(
fp
,
"%#018llx %c "
,
(
u64
)
self
->
ip
,
o
);
ret
+=
repsep_
snprintf
(
bf
,
size
,
"%#018llx %c "
,
self
->
ip
,
o
);
}
ret
+=
repsep_
fprintf
(
fp
,
"[%c] "
,
self
->
level
);
ret
+=
repsep_
snprintf
(
bf
+
ret
,
size
-
ret
,
"[%c] "
,
self
->
level
);
if
(
self
->
ms
.
sym
)
ret
+=
repsep_fprintf
(
fp
,
"%s"
,
self
->
ms
.
sym
->
name
);
ret
+=
repsep_snprintf
(
bf
+
ret
,
size
-
ret
,
"%s"
,
self
->
ms
.
sym
->
name
);
else
ret
+=
repsep_
fprintf
(
fp
,
"%#016llx"
,
(
u64
)
self
->
ip
);
ret
+=
repsep_
snprintf
(
bf
+
ret
,
size
-
ret
,
"%#016llx"
,
self
->
ip
);
return
ret
;
}
...
...
@@ -231,10 +235,10 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
return
strcmp
(
sym_l
->
name
,
sym_r
->
name
);
}
s
ize_t
sort__parent_print
(
FILE
*
fp
,
struct
hist_entry
*
self
,
unsigned
int
width
)
s
tatic
int
hist_entry__parent_snprintf
(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
)
{
return
repsep_
fprintf
(
fp
,
"%-*s"
,
width
,
return
repsep_
snprintf
(
bf
,
size
,
"%-*s"
,
width
,
self
->
parent
?
self
->
parent
->
name
:
"[other]"
);
}
...
...
@@ -260,9 +264,8 @@ int sort_dimension__add(const char *tok)
char
err
[
BUFSIZ
];
regerror
(
ret
,
&
parent_regex
,
err
,
sizeof
(
err
));
fprintf
(
stderr
,
"Invalid regex: %s
\n
%s"
,
parent_pattern
,
err
);
exit
(
-
1
);
pr_err
(
"Invalid regex: %s
\n
%s"
,
parent_pattern
,
err
);
return
-
EINVAL
;
}
sort__has_parent
=
1
;
}
...
...
tools/perf/util/sort.h
View file @
70a7c127
...
...
@@ -49,12 +49,12 @@ struct hist_entry {
u64
ip
;
char
level
;
struct
symbol
*
parent
;
struct
callchain_node
callchain
;
union
{
unsigned
long
position
;
struct
hist_entry
*
pair
;
struct
rb_root
sorted_chain
;
};
struct
callchain_node
callchain
[
0
];
};
enum
sort_type
{
...
...
@@ -76,7 +76,8 @@ struct sort_entry {
int64_t
(
*
cmp
)(
struct
hist_entry
*
,
struct
hist_entry
*
);
int64_t
(
*
collapse
)(
struct
hist_entry
*
,
struct
hist_entry
*
);
size_t
(
*
print
)(
FILE
*
fp
,
struct
hist_entry
*
,
unsigned
int
width
);
int
(
*
snprintf
)(
struct
hist_entry
*
self
,
char
*
bf
,
size_t
size
,
unsigned
int
width
);
unsigned
int
*
width
;
bool
elide
;
};
...
...
@@ -86,7 +87,6 @@ extern struct list_head hist_entry__sort_list;
void
setup_sorting
(
const
char
*
const
usagestr
[],
const
struct
option
*
opts
);
extern
int
repsep_fprintf
(
FILE
*
fp
,
const
char
*
fmt
,
...);
extern
size_t
sort__thread_print
(
FILE
*
,
struct
hist_entry
*
,
unsigned
int
);
extern
size_t
sort__comm_print
(
FILE
*
,
struct
hist_entry
*
,
unsigned
int
);
extern
size_t
sort__dso_print
(
FILE
*
,
struct
hist_entry
*
,
unsigned
int
);
...
...
tools/perf/util/string.h
deleted
100644 → 0
View file @
40b91cd1
#ifndef __PERF_STRING_H_
#define __PERF_STRING_H_
#include <stdbool.h>
#include "types.h"
s64
perf_atoll
(
const
char
*
str
);
char
**
argv_split
(
const
char
*
str
,
int
*
argcp
);
void
argv_free
(
char
**
argv
);
bool
strglobmatch
(
const
char
*
str
,
const
char
*
pat
);
bool
strlazymatch
(
const
char
*
str
,
const
char
*
pat
);
#define _STR(x) #x
#define STR(x) _STR(x)
#endif
/* __PERF_STRING_H */
tools/perf/util/thread.c
View file @
70a7c127
...
...
@@ -38,15 +38,6 @@ int find_all_tid(int pid, pid_t ** all_tid)
return
ret
;
}
void
map_groups__init
(
struct
map_groups
*
self
)
{
int
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
{
self
->
maps
[
i
]
=
RB_ROOT
;
INIT_LIST_HEAD
(
&
self
->
removed_maps
[
i
]);
}
}
static
struct
thread
*
thread__new
(
pid_t
pid
)
{
struct
thread
*
self
=
zalloc
(
sizeof
(
*
self
));
...
...
@@ -62,28 +53,6 @@ static struct thread *thread__new(pid_t pid)
return
self
;
}
static
void
map_groups__flush
(
struct
map_groups
*
self
)
{
int
type
;
for
(
type
=
0
;
type
<
MAP__NR_TYPES
;
type
++
)
{
struct
rb_root
*
root
=
&
self
->
maps
[
type
];
struct
rb_node
*
next
=
rb_first
(
root
);
while
(
next
)
{
struct
map
*
pos
=
rb_entry
(
next
,
struct
map
,
rb_node
);
next
=
rb_next
(
&
pos
->
rb_node
);
rb_erase
(
&
pos
->
rb_node
,
root
);
/*
* We may have references to this map, for
* instance in some hist_entry instances, so
* just move them to a separate list.
*/
list_add_tail
(
&
pos
->
node
,
&
self
->
removed_maps
[
pos
->
type
]);
}
}
}
int
thread__set_comm
(
struct
thread
*
self
,
const
char
*
comm
)
{
int
err
;
...
...
@@ -110,69 +79,10 @@ int thread__comm_len(struct thread *self)
return
self
->
comm_len
;
}
size_t
__map_groups__fprintf_maps
(
struct
map_groups
*
self
,
enum
map_type
type
,
FILE
*
fp
)
{
size_t
printed
=
fprintf
(
fp
,
"%s:
\n
"
,
map_type__name
[
type
]);
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
&
self
->
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
pos
=
rb_entry
(
nd
,
struct
map
,
rb_node
);
printed
+=
fprintf
(
fp
,
"Map:"
);
printed
+=
map__fprintf
(
pos
,
fp
);
if
(
verbose
>
2
)
{
printed
+=
dso__fprintf
(
pos
->
dso
,
type
,
fp
);
printed
+=
fprintf
(
fp
,
"--
\n
"
);
}
}
return
printed
;
}
size_t
map_groups__fprintf_maps
(
struct
map_groups
*
self
,
FILE
*
fp
)
{
size_t
printed
=
0
,
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
printed
+=
__map_groups__fprintf_maps
(
self
,
i
,
fp
);
return
printed
;
}
static
size_t
__map_groups__fprintf_removed_maps
(
struct
map_groups
*
self
,
enum
map_type
type
,
FILE
*
fp
)
{
struct
map
*
pos
;
size_t
printed
=
0
;
list_for_each_entry
(
pos
,
&
self
->
removed_maps
[
type
],
node
)
{
printed
+=
fprintf
(
fp
,
"Map:"
);
printed
+=
map__fprintf
(
pos
,
fp
);
if
(
verbose
>
1
)
{
printed
+=
dso__fprintf
(
pos
->
dso
,
type
,
fp
);
printed
+=
fprintf
(
fp
,
"--
\n
"
);
}
}
return
printed
;
}
static
size_t
map_groups__fprintf_removed_maps
(
struct
map_groups
*
self
,
FILE
*
fp
)
{
size_t
printed
=
0
,
i
;
for
(
i
=
0
;
i
<
MAP__NR_TYPES
;
++
i
)
printed
+=
__map_groups__fprintf_removed_maps
(
self
,
i
,
fp
);
return
printed
;
}
static
size_t
map_groups__fprintf
(
struct
map_groups
*
self
,
FILE
*
fp
)
{
size_t
printed
=
map_groups__fprintf_maps
(
self
,
fp
);
printed
+=
fprintf
(
fp
,
"Removed maps:
\n
"
);
return
printed
+
map_groups__fprintf_removed_maps
(
self
,
fp
);
}
static
size_t
thread__fprintf
(
struct
thread
*
self
,
FILE
*
fp
)
{
return
fprintf
(
fp
,
"Thread %d %s
\n
"
,
self
->
pid
,
self
->
comm
)
+
map_groups__fprintf
(
&
self
->
mg
,
fp
);
map_groups__fprintf
(
&
self
->
mg
,
verbose
,
fp
);
}
struct
thread
*
perf_session__findnew
(
struct
perf_session
*
self
,
pid_t
pid
)
...
...
@@ -214,87 +124,12 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
return
th
;
}
static
int
map_groups__fixup_overlappings
(
struct
map_groups
*
self
,
struct
map
*
map
)
{
struct
rb_root
*
root
=
&
self
->
maps
[
map
->
type
];
struct
rb_node
*
next
=
rb_first
(
root
);
while
(
next
)
{
struct
map
*
pos
=
rb_entry
(
next
,
struct
map
,
rb_node
);
next
=
rb_next
(
&
pos
->
rb_node
);
if
(
!
map__overlap
(
pos
,
map
))
continue
;
if
(
verbose
>=
2
)
{
fputs
(
"overlapping maps:
\n
"
,
stderr
);
map__fprintf
(
map
,
stderr
);
map__fprintf
(
pos
,
stderr
);
}
rb_erase
(
&
pos
->
rb_node
,
root
);
/*
* We may have references to this map, for instance in some
* hist_entry instances, so just move them to a separate
* list.
*/
list_add_tail
(
&
pos
->
node
,
&
self
->
removed_maps
[
map
->
type
]);
/*
* Now check if we need to create new maps for areas not
* overlapped by the new map:
*/
if
(
map
->
start
>
pos
->
start
)
{
struct
map
*
before
=
map__clone
(
pos
);
if
(
before
==
NULL
)
return
-
ENOMEM
;
before
->
end
=
map
->
start
-
1
;
map_groups__insert
(
self
,
before
);
if
(
verbose
>=
2
)
map__fprintf
(
before
,
stderr
);
}
if
(
map
->
end
<
pos
->
end
)
{
struct
map
*
after
=
map__clone
(
pos
);
if
(
after
==
NULL
)
return
-
ENOMEM
;
after
->
start
=
map
->
end
+
1
;
map_groups__insert
(
self
,
after
);
if
(
verbose
>=
2
)
map__fprintf
(
after
,
stderr
);
}
}
return
0
;
}
void
thread__insert_map
(
struct
thread
*
self
,
struct
map
*
map
)
{
map_groups__fixup_overlappings
(
&
self
->
mg
,
map
);
map_groups__fixup_overlappings
(
&
self
->
mg
,
map
,
verbose
,
stderr
);
map_groups__insert
(
&
self
->
mg
,
map
);
}
/*
* XXX This should not really _copy_ te maps, but refcount them.
*/
static
int
map_groups__clone
(
struct
map_groups
*
self
,
struct
map_groups
*
parent
,
enum
map_type
type
)
{
struct
rb_node
*
nd
;
for
(
nd
=
rb_first
(
&
parent
->
maps
[
type
]);
nd
;
nd
=
rb_next
(
nd
))
{
struct
map
*
map
=
rb_entry
(
nd
,
struct
map
,
rb_node
);
struct
map
*
new
=
map__clone
(
map
);
if
(
new
==
NULL
)
return
-
ENOMEM
;
map_groups__insert
(
self
,
new
);
}
return
0
;
}
int
thread__fork
(
struct
thread
*
self
,
struct
thread
*
parent
)
{
int
i
;
...
...
tools/perf/util/util.h
View file @
70a7c127
...
...
@@ -42,12 +42,14 @@
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _BSD_SOURCE 1
#define HAS_BOOL
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
...
...
@@ -78,6 +80,7 @@
#include <pwd.h>
#include <inttypes.h>
#include "../../../include/linux/magic.h"
#include "types.h"
#ifndef NO_ICONV
...
...
@@ -415,4 +418,13 @@ void git_qsort(void *base, size_t nmemb, size_t size,
int
mkdir_p
(
char
*
path
,
mode_t
mode
);
int
copyfile
(
const
char
*
from
,
const
char
*
to
);
s64
perf_atoll
(
const
char
*
str
);
char
**
argv_split
(
const
char
*
str
,
int
*
argcp
);
void
argv_free
(
char
**
argv
);
bool
strglobmatch
(
const
char
*
str
,
const
char
*
pat
);
bool
strlazymatch
(
const
char
*
str
,
const
char
*
pat
);
#define _STR(x) #x
#define STR(x) _STR(x)
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment