Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
c73a3cb3
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c73a3cb3
编写于
10月 15, 2011
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'perf/core' of
git://github.com/acmel/linux
into perf/core
上级
910e94dd
6c3c5b26
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
375 addition
and
165 deletion
+375
-165
tools/perf/builtin-top.c
tools/perf/builtin-top.c
+20
-5
tools/perf/perf.c
tools/perf/perf.c
+24
-0
tools/perf/perf.h
tools/perf/perf.h
+2
-0
tools/perf/util/header.c
tools/perf/util/header.c
+1
-1
tools/perf/util/hist.c
tools/perf/util/hist.c
+20
-4
tools/perf/util/hist.h
tools/perf/util/hist.h
+8
-3
tools/perf/util/sort.h
tools/perf/util/sort.h
+1
-0
tools/perf/util/ui/browser.c
tools/perf/util/ui/browser.c
+155
-73
tools/perf/util/ui/browser.h
tools/perf/util/ui/browser.h
+5
-5
tools/perf/util/ui/browsers/annotate.c
tools/perf/util/ui/browsers/annotate.c
+78
-17
tools/perf/util/ui/browsers/hists.c
tools/perf/util/ui/browsers/hists.c
+57
-53
tools/perf/util/ui/browsers/map.c
tools/perf/util/ui/browsers/map.c
+2
-4
tools/perf/util/ui/helpline.h
tools/perf/util/ui/helpline.h
+2
-0
未找到文件。
tools/perf/builtin-top.c
浏览文件 @
c73a3cb3
...
...
@@ -304,7 +304,7 @@ static void print_sym_table(void)
hists__collapse_resort_threaded
(
&
top
.
sym_evsel
->
hists
);
hists__output_resort_threaded
(
&
top
.
sym_evsel
->
hists
);
hists__decay_entries
(
&
top
.
sym_evsel
->
hists
);
hists__decay_entries
_threaded
(
&
top
.
sym_evsel
->
hists
);
hists__output_recalc_col_len
(
&
top
.
sym_evsel
->
hists
,
winsize
.
ws_row
-
3
);
putchar
(
'\n'
);
hists__fprintf
(
&
top
.
sym_evsel
->
hists
,
NULL
,
false
,
false
,
...
...
@@ -555,7 +555,7 @@ static void perf_top__sort_new_samples(void *arg)
hists__collapse_resort_threaded
(
&
t
->
sym_evsel
->
hists
);
hists__output_resort_threaded
(
&
t
->
sym_evsel
->
hists
);
hists__decay_entries
(
&
t
->
sym_evsel
->
hists
);
hists__decay_entries
_threaded
(
&
t
->
sym_evsel
->
hists
);
hists__output_recalc_col_len
(
&
t
->
sym_evsel
->
hists
,
winsize
.
ws_row
-
3
);
}
...
...
@@ -585,16 +585,31 @@ static void *display_thread(void *arg __used)
tc
.
c_cc
[
VMIN
]
=
0
;
tc
.
c_cc
[
VTIME
]
=
0
;
pthread__unblock_sigwinch
();
repeat:
delay_msecs
=
top
.
delay_secs
*
1000
;
tcsetattr
(
0
,
TCSANOW
,
&
tc
);
/* trash return*/
getc
(
stdin
);
do
{
while
(
1
)
{
print_sym_table
();
}
while
(
!
poll
(
&
stdin_poll
,
1
,
delay_msecs
)
==
1
);
/*
* Either timeout expired or we got an EINTR due to SIGWINCH,
* refresh screen in both cases.
*/
switch
(
poll
(
&
stdin_poll
,
1
,
delay_msecs
))
{
case
0
:
continue
;
case
-
1
:
if
(
errno
==
EINTR
)
continue
;
/* Fall trhu */
default:
goto
process_hotkey
;
}
}
process_hotkey:
c
=
getc
(
stdin
);
tcsetattr
(
0
,
TCSAFLUSH
,
&
save
);
...
...
tools/perf/perf.c
浏览文件 @
c73a3cb3
...
...
@@ -427,6 +427,24 @@ static void get_debugfs_mntpt(void)
debugfs_mntpt
[
0
]
=
'\0'
;
}
static
void
pthread__block_sigwinch
(
void
)
{
sigset_t
set
;
sigemptyset
(
&
set
);
sigaddset
(
&
set
,
SIGWINCH
);
pthread_sigmask
(
SIG_BLOCK
,
&
set
,
NULL
);
}
void
pthread__unblock_sigwinch
(
void
)
{
sigset_t
set
;
sigemptyset
(
&
set
);
sigaddset
(
&
set
,
SIGWINCH
);
pthread_sigmask
(
SIG_UNBLOCK
,
&
set
,
NULL
);
}
int
main
(
int
argc
,
const
char
**
argv
)
{
const
char
*
cmd
;
...
...
@@ -480,6 +498,12 @@ int main(int argc, const char **argv)
* time.
*/
setup_path
();
/*
* Block SIGWINCH notifications so that the thread that wants it can
* unblock and get syscalls like select interrupted instead of waiting
* forever while the signal goes to some other non interested thread.
*/
pthread__block_sigwinch
();
while
(
1
)
{
static
int
done_help
;
...
...
tools/perf/perf.h
浏览文件 @
c73a3cb3
...
...
@@ -183,4 +183,6 @@ struct ip_callchain {
extern
bool
perf_host
,
perf_guest
;
extern
const
char
perf_version_string
[];
void
pthread__unblock_sigwinch
(
void
);
#endif
tools/perf/util/header.c
浏览文件 @
c73a3cb3
...
...
@@ -1289,7 +1289,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
if
(
access
(
linkname
,
F_OK
))
goto
out_free
;
if
(
readlink
(
linkname
,
filename
,
size
)
<
0
)
if
(
readlink
(
linkname
,
filename
,
size
-
1
)
<
0
)
goto
out_free
;
if
(
unlink
(
linkname
))
...
...
tools/perf/util/hist.c
浏览文件 @
c73a3cb3
...
...
@@ -100,13 +100,15 @@ static void hist_entry__decay(struct hist_entry *he)
static
bool
hists__decay_entry
(
struct
hists
*
hists
,
struct
hist_entry
*
he
)
{
if
(
he
->
period
==
0
)
return
true
;
hists
->
stats
.
total_period
-=
he
->
period
;
hist_entry__decay
(
he
);
hists
->
stats
.
total_period
+=
he
->
period
;
return
he
->
period
==
0
;
}
void
hists__decay_entries
(
struct
hists
*
hists
)
static
void
__hists__decay_entries
(
struct
hists
*
hists
,
bool
threaded
)
{
struct
rb_node
*
next
=
rb_first
(
&
hists
->
entries
);
struct
hist_entry
*
n
;
...
...
@@ -114,11 +116,15 @@ void hists__decay_entries(struct hists *hists)
while
(
next
)
{
n
=
rb_entry
(
next
,
struct
hist_entry
,
rb_node
);
next
=
rb_next
(
&
n
->
rb_node
);
if
(
hists__decay_entry
(
hists
,
n
))
{
/*
* We may be annotating this, for instance, so keep it here in
* case some it gets new samples, we'll eventually free it when
* the user stops browsing and it agains gets fully decayed.
*/
if
(
hists__decay_entry
(
hists
,
n
)
&&
!
n
->
used
)
{
rb_erase
(
&
n
->
rb_node
,
&
hists
->
entries
);
if
(
sort__need_collapse
)
if
(
sort__need_collapse
||
threaded
)
rb_erase
(
&
n
->
rb_node_in
,
&
hists
->
entries_collapsed
);
hist_entry__free
(
n
);
...
...
@@ -127,6 +133,16 @@ void hists__decay_entries(struct hists *hists)
}
}
void
hists__decay_entries
(
struct
hists
*
hists
)
{
return
__hists__decay_entries
(
hists
,
false
);
}
void
hists__decay_entries_threaded
(
struct
hists
*
hists
)
{
return
__hists__decay_entries
(
hists
,
true
);
}
/*
* histogram, sorted on item, collects periods
*/
...
...
tools/perf/util/hist.h
浏览文件 @
c73a3cb3
...
...
@@ -79,6 +79,7 @@ void hists__collapse_resort(struct hists *self);
void
hists__collapse_resort_threaded
(
struct
hists
*
hists
);
void
hists__decay_entries
(
struct
hists
*
hists
);
void
hists__decay_entries_threaded
(
struct
hists
*
hists
);
void
hists__output_recalc_col_len
(
struct
hists
*
hists
,
int
max_rows
);
void
hists__inc_nr_events
(
struct
hists
*
self
,
u32
type
);
...
...
@@ -103,16 +104,20 @@ struct perf_evlist;
#ifdef NO_NEWT_SUPPORT
static
inline
int
perf_evlist__tui_browse_hists
(
struct
perf_evlist
*
evlist
__used
,
const
char
*
help
__used
,
void
(
*
timer
)(
void
*
arg
)
__used
,
void
*
arg
,
const
char
*
help
__used
,
void
(
*
timer
)(
void
*
arg
)
__used
,
void
*
arg
__used
,
int
refresh
__used
)
{
return
0
;
}
static
inline
int
hist_entry__tui_annotate
(
struct
hist_entry
*
self
__used
,
int
evidx
__used
,
int
nr_events
__used
,
int
evidx
__used
,
int
nr_events
__used
,
void
(
*
timer
)(
void
*
arg
)
__used
,
void
*
arg
__used
,
int
delay_secs
__used
);
void
*
arg
__used
,
int
delay_secs
__used
)
{
return
0
;
}
...
...
tools/perf/util/sort.h
浏览文件 @
c73a3cb3
...
...
@@ -64,6 +64,7 @@ struct hist_entry {
bool
init_have_children
;
char
level
;
bool
used
;
u8
filtered
;
struct
symbol
*
parent
;
union
{
...
...
tools/perf/util/ui/browser.c
浏览文件 @
c73a3cb3
#include "../util.h"
#include "../../perf.h"
#include "libslang.h"
#include <newt.h>
#include "ui.h"
#include <linux/compiler.h>
#include <linux/list.h>
...
...
@@ -8,8 +11,8 @@
#include "browser.h"
#include "helpline.h"
#include "../color.h"
#include "../util.h"
#include <stdio.h>
int
newtGetKey
(
void
);
static
int
ui_browser__percent_color
(
double
percent
,
bool
current
)
{
...
...
@@ -39,31 +42,62 @@ void ui_browser__gotorc(struct ui_browser *self, int y, int x)
SLsmg_gotorc
(
self
->
y
+
y
,
self
->
x
+
x
);
}
static
struct
list_head
*
ui_browser__list_head_filter_entries
(
struct
ui_browser
*
browser
,
struct
list_head
*
pos
)
{
do
{
if
(
!
browser
->
filter
||
!
browser
->
filter
(
browser
,
pos
))
return
pos
;
pos
=
pos
->
next
;
}
while
(
pos
!=
browser
->
entries
);
return
NULL
;
}
static
struct
list_head
*
ui_browser__list_head_filter_prev_entries
(
struct
ui_browser
*
browser
,
struct
list_head
*
pos
)
{
do
{
if
(
!
browser
->
filter
||
!
browser
->
filter
(
browser
,
pos
))
return
pos
;
pos
=
pos
->
prev
;
}
while
(
pos
!=
browser
->
entries
);
return
NULL
;
}
void
ui_browser__list_head_seek
(
struct
ui_browser
*
self
,
off_t
offset
,
int
whence
)
{
struct
list_head
*
head
=
self
->
entries
;
struct
list_head
*
pos
;
if
(
self
->
nr_entries
==
0
)
return
;
switch
(
whence
)
{
case
SEEK_SET
:
pos
=
head
->
next
;
pos
=
ui_browser__list_head_filter_entries
(
self
,
head
->
next
)
;
break
;
case
SEEK_CUR
:
pos
=
self
->
top
;
break
;
case
SEEK_END
:
pos
=
head
->
prev
;
pos
=
ui_browser__list_head_filter_prev_entries
(
self
,
head
->
prev
)
;
break
;
default:
return
;
}
assert
(
pos
!=
NULL
);
if
(
offset
>
0
)
{
while
(
offset
--
!=
0
)
pos
=
pos
->
next
;
pos
=
ui_browser__list_head_filter_entries
(
self
,
pos
->
next
)
;
}
else
{
while
(
offset
++
!=
0
)
pos
=
pos
->
prev
;
pos
=
ui_browser__list_head_filter_prev_entries
(
self
,
pos
->
prev
)
;
}
self
->
top
=
pos
;
...
...
@@ -127,11 +161,8 @@ bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row)
void
ui_browser__refresh_dimensions
(
struct
ui_browser
*
self
)
{
int
cols
,
rows
;
newtGetScreenSize
(
&
cols
,
&
rows
);
self
->
width
=
cols
-
1
;
self
->
height
=
rows
-
2
;
self
->
width
=
SLtt_Screen_Cols
-
1
;
self
->
height
=
SLtt_Screen_Rows
-
2
;
self
->
y
=
1
;
self
->
x
=
0
;
}
...
...
@@ -142,26 +173,11 @@ void ui_browser__reset_index(struct ui_browser *self)
self
->
seek
(
self
,
0
,
SEEK_SET
);
}
void
ui_browser__add_exit_key
(
struct
ui_browser
*
self
,
int
key
)
{
newtFormAddHotKey
(
self
->
form
,
key
);
}
void
ui_browser__add_exit_keys
(
struct
ui_browser
*
self
,
int
keys
[])
{
int
i
=
0
;
while
(
keys
[
i
]
&&
i
<
64
)
{
ui_browser__add_exit_key
(
self
,
keys
[
i
]);
++
i
;
}
}
void
__ui_browser__show_title
(
struct
ui_browser
*
browser
,
const
char
*
title
)
{
SLsmg_gotorc
(
0
,
0
);
ui_browser__set_color
(
browser
,
NEWT_COLORSET_ROOT
);
slsmg_write_nstring
(
title
,
browser
->
width
);
slsmg_write_nstring
(
title
,
browser
->
width
+
1
);
}
void
ui_browser__show_title
(
struct
ui_browser
*
browser
,
const
char
*
title
)
...
...
@@ -174,77 +190,143 @@ void ui_browser__show_title(struct ui_browser *browser, const char *title)
int
ui_browser__show
(
struct
ui_browser
*
self
,
const
char
*
title
,
const
char
*
helpline
,
...)
{
int
err
;
va_list
ap
;
int
keys
[]
=
{
NEWT_KEY_UP
,
NEWT_KEY_DOWN
,
NEWT_KEY_PGUP
,
NEWT_KEY_PGDN
,
NEWT_KEY_HOME
,
NEWT_KEY_END
,
' '
,
NEWT_KEY_LEFT
,
NEWT_KEY_ESCAPE
,
'q'
,
CTRL
(
'c'
),
0
};
if
(
self
->
form
!=
NULL
)
newtFormDestroy
(
self
->
form
);
ui_browser__refresh_dimensions
(
self
);
self
->
form
=
newtForm
(
NULL
,
NULL
,
0
);
if
(
self
->
form
==
NULL
)
return
-
1
;
self
->
sb
=
newtVerticalScrollbar
(
self
->
width
,
1
,
self
->
height
,
HE_COLORSET_NORMAL
,
HE_COLORSET_SELECTED
);
if
(
self
->
sb
==
NULL
)
return
-
1
;
pthread_mutex_lock
(
&
ui__lock
);
__ui_browser__show_title
(
self
,
title
);
ui_browser__add_exit_keys
(
self
,
keys
);
newtFormAddComponent
(
self
->
form
,
self
->
sb
);
self
->
title
=
title
;
free
(
self
->
helpline
);
self
->
helpline
=
NULL
;
va_start
(
ap
,
helpline
);
ui_helpline__vpush
(
helpline
,
ap
);
err
=
vasprintf
(
&
self
->
helpline
,
helpline
,
ap
);
va_end
(
ap
);
if
(
err
>
0
)
ui_helpline__push
(
self
->
helpline
);
pthread_mutex_unlock
(
&
ui__lock
);
return
0
;
return
err
?
0
:
-
1
;
}
void
ui_browser__hide
(
struct
ui_browser
*
self
)
void
ui_browser__hide
(
struct
ui_browser
*
browser
__used
)
{
pthread_mutex_lock
(
&
ui__lock
);
newtFormDestroy
(
self
->
form
);
self
->
form
=
NULL
;
ui_helpline__pop
();
pthread_mutex_unlock
(
&
ui__lock
);
}
int
ui_browser__refresh
(
struct
ui_browser
*
self
)
static
void
ui_browser__scrollbar_set
(
struct
ui_browser
*
browser
)
{
int
height
=
browser
->
height
,
h
=
0
,
pct
=
0
,
col
=
browser
->
width
,
row
=
browser
->
y
-
1
;
if
(
browser
->
nr_entries
>
1
)
{
pct
=
((
browser
->
index
*
(
browser
->
height
-
1
))
/
(
browser
->
nr_entries
-
1
));
}
while
(
h
<
height
)
{
ui_browser__gotorc
(
browser
,
row
++
,
col
);
SLsmg_set_char_set
(
1
);
SLsmg_write_char
(
h
==
pct
?
SLSMG_DIAMOND_CHAR
:
SLSMG_BOARD_CHAR
);
SLsmg_set_char_set
(
0
);
++
h
;
}
}
static
int
__ui_browser__refresh
(
struct
ui_browser
*
browser
)
{
int
row
;
row
=
browser
->
refresh
(
browser
);
ui_browser__set_color
(
browser
,
HE_COLORSET_NORMAL
);
SLsmg_fill_region
(
browser
->
y
+
row
,
browser
->
x
,
browser
->
height
-
row
,
browser
->
width
,
' '
);
ui_browser__scrollbar_set
(
browser
);
return
0
;
}
int
ui_browser__refresh
(
struct
ui_browser
*
browser
)
{
pthread_mutex_lock
(
&
ui__lock
);
newtScrollbarSet
(
self
->
sb
,
self
->
index
,
self
->
nr_entries
-
1
);
row
=
self
->
refresh
(
self
);
ui_browser__set_color
(
self
,
HE_COLORSET_NORMAL
);
SLsmg_fill_region
(
self
->
y
+
row
,
self
->
x
,
self
->
height
-
row
,
self
->
width
,
' '
);
__ui_browser__refresh
(
browser
);
pthread_mutex_unlock
(
&
ui__lock
);
return
0
;
}
int
ui_browser__run
(
struct
ui_browser
*
self
)
/*
* Here we're updating nr_entries _after_ we started browsing, i.e. we have to
* forget about any reference to any entry in the underlying data structure,
* that is why we do a SEEK_SET. Think about 'perf top' in the hists browser
* after an output_resort and hist decay.
*/
void
ui_browser__update_nr_entries
(
struct
ui_browser
*
browser
,
u32
nr_entries
)
{
off_t
offset
=
nr_entries
-
browser
->
nr_entries
;
browser
->
nr_entries
=
nr_entries
;
if
(
offset
<
0
)
{
if
(
browser
->
top_idx
<
(
u64
)
-
offset
)
offset
=
-
browser
->
top_idx
;
browser
->
index
+=
offset
;
browser
->
top_idx
+=
offset
;
}
browser
->
top
=
NULL
;
browser
->
seek
(
browser
,
browser
->
top_idx
,
SEEK_SET
);
}
int
ui_browser__run
(
struct
ui_browser
*
self
,
int
delay_secs
)
{
struct
newtExitStruct
es
;
int
err
,
key
;
struct
timeval
timeout
,
*
ptimeout
=
delay_secs
?
&
timeout
:
NULL
;
if
(
ui_browser__refresh
(
self
)
<
0
)
return
-
1
;
pthread__unblock_sigwinch
();
while
(
1
)
{
off_t
offset
;
fd_set
read_set
;
newtFormRun
(
self
->
form
,
&
es
);
pthread_mutex_lock
(
&
ui__lock
);
err
=
__ui_browser__refresh
(
self
);
SLsmg_refresh
();
pthread_mutex_unlock
(
&
ui__lock
);
if
(
err
<
0
)
break
;
FD_ZERO
(
&
read_set
);
FD_SET
(
0
,
&
read_set
);
if
(
delay_secs
)
{
timeout
.
tv_sec
=
delay_secs
;
timeout
.
tv_usec
=
0
;
}
if
(
es
.
reason
!=
NEWT_EXIT_HOTKEY
)
err
=
select
(
1
,
&
read_set
,
NULL
,
NULL
,
ptimeout
);
if
(
err
>
0
&&
FD_ISSET
(
0
,
&
read_set
))
key
=
newtGetKey
();
else
if
(
err
==
0
)
break
;
switch
(
es
.
u
.
key
)
{
else
{
pthread_mutex_lock
(
&
ui__lock
);
SLtt_get_screen_size
();
SLsmg_reinit_smg
();
pthread_mutex_unlock
(
&
ui__lock
);
ui_browser__refresh_dimensions
(
self
);
__ui_browser__show_title
(
self
,
self
->
title
);
ui_helpline__puts
(
self
->
helpline
);
continue
;
}
switch
(
key
)
{
case
NEWT_KEY_DOWN
:
if
(
self
->
index
==
self
->
nr_entries
-
1
)
break
;
...
...
@@ -301,10 +383,8 @@ int ui_browser__run(struct ui_browser *self)
self
->
seek
(
self
,
-
offset
,
SEEK_END
);
break
;
default:
return
es
.
u
.
key
;
return
key
;
}
if
(
ui_browser__refresh
(
self
)
<
0
)
return
-
1
;
}
return
-
1
;
}
...
...
@@ -316,27 +396,29 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *self)
int
row
=
0
;
if
(
self
->
top
==
NULL
||
self
->
top
==
self
->
entries
)
self
->
top
=
head
->
next
;
self
->
top
=
ui_browser__list_head_filter_entries
(
self
,
head
->
next
)
;
pos
=
self
->
top
;
list_for_each_from
(
pos
,
head
)
{
ui_browser__gotorc
(
self
,
row
,
0
);
self
->
write
(
self
,
pos
,
row
);
if
(
++
row
==
self
->
height
)
break
;
if
(
!
self
->
filter
||
!
self
->
filter
(
self
,
pos
))
{
ui_browser__gotorc
(
self
,
row
,
0
);
self
->
write
(
self
,
pos
,
row
);
if
(
++
row
==
self
->
height
)
break
;
}
}
return
row
;
}
static
struct
newtPercentTreeC
olors
{
static
struct
ui_browser__c
olors
{
const
char
*
topColorFg
,
*
topColorBg
;
const
char
*
mediumColorFg
,
*
mediumColorBg
;
const
char
*
normalColorFg
,
*
normalColorBg
;
const
char
*
selColorFg
,
*
selColorBg
;
const
char
*
codeColorFg
,
*
codeColorBg
;
}
defaultPercentTreeC
olors
=
{
}
ui_browser__default_c
olors
=
{
"red"
,
"lightgray"
,
"green"
,
"lightgray"
,
"black"
,
"lightgray"
,
...
...
@@ -346,7 +428,7 @@ static struct newtPercentTreeColors {
void
ui_browser__init
(
void
)
{
struct
newtPercentTreeColors
*
c
=
&
defaultPercentTreeC
olors
;
struct
ui_browser__colors
*
c
=
&
ui_browser__default_c
olors
;
sltt_set_color
(
HE_COLORSET_TOP
,
NULL
,
c
->
topColorFg
,
c
->
topColorBg
);
sltt_set_color
(
HE_COLORSET_MEDIUM
,
NULL
,
c
->
mediumColorFg
,
c
->
mediumColorBg
);
...
...
tools/perf/util/ui/browser.h
浏览文件 @
c73a3cb3
...
...
@@ -2,7 +2,6 @@
#define _PERF_UI_BROWSER_H_ 1
#include <stdbool.h>
#include <newt.h>
#include <sys/types.h>
#include "../types.h"
...
...
@@ -13,14 +12,16 @@
#define HE_COLORSET_CODE 54
struct
ui_browser
{
newtComponent
form
,
sb
;
u64
index
,
top_idx
;
void
*
top
,
*
entries
;
u16
y
,
x
,
width
,
height
;
void
*
priv
;
const
char
*
title
;
char
*
helpline
;
unsigned
int
(
*
refresh
)(
struct
ui_browser
*
self
);
void
(
*
write
)(
struct
ui_browser
*
self
,
void
*
entry
,
int
row
);
void
(
*
seek
)(
struct
ui_browser
*
self
,
off_t
offset
,
int
whence
);
bool
(
*
filter
)(
struct
ui_browser
*
self
,
void
*
entry
);
u32
nr_entries
;
};
...
...
@@ -32,15 +33,14 @@ void ui_browser__refresh_dimensions(struct ui_browser *self);
void
ui_browser__reset_index
(
struct
ui_browser
*
self
);
void
ui_browser__gotorc
(
struct
ui_browser
*
self
,
int
y
,
int
x
);
void
ui_browser__add_exit_key
(
struct
ui_browser
*
self
,
int
key
);
void
ui_browser__add_exit_keys
(
struct
ui_browser
*
self
,
int
keys
[]);
void
__ui_browser__show_title
(
struct
ui_browser
*
browser
,
const
char
*
title
);
void
ui_browser__show_title
(
struct
ui_browser
*
browser
,
const
char
*
title
);
int
ui_browser__show
(
struct
ui_browser
*
self
,
const
char
*
title
,
const
char
*
helpline
,
...);
void
ui_browser__hide
(
struct
ui_browser
*
self
);
int
ui_browser__refresh
(
struct
ui_browser
*
self
);
int
ui_browser__run
(
struct
ui_browser
*
self
);
int
ui_browser__run
(
struct
ui_browser
*
browser
,
int
delay_secs
);
void
ui_browser__update_nr_entries
(
struct
ui_browser
*
browser
,
u32
nr_entries
);
void
ui_browser__rb_tree_seek
(
struct
ui_browser
*
self
,
off_t
offset
,
int
whence
);
unsigned
int
ui_browser__rb_tree_refresh
(
struct
ui_browser
*
self
);
...
...
tools/perf/util/ui/browsers/annotate.c
浏览文件 @
c73a3cb3
...
...
@@ -21,12 +21,16 @@ struct annotate_browser {
struct
rb_root
entries
;
struct
rb_node
*
curr_hot
;
struct
objdump_line
*
selection
;
int
nr_asm_entries
;
int
nr_entries
;
bool
hide_src_code
;
};
struct
objdump_line_rb_node
{
struct
rb_node
rb_node
;
double
percent
;
u32
idx
;
int
idx_asm
;
};
static
inline
...
...
@@ -35,10 +39,22 @@ struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self)
return
(
struct
objdump_line_rb_node
*
)(
self
+
1
);
}
static
bool
objdump_line__filter
(
struct
ui_browser
*
browser
,
void
*
entry
)
{
struct
annotate_browser
*
ab
=
container_of
(
browser
,
struct
annotate_browser
,
b
);
if
(
ab
->
hide_src_code
)
{
struct
objdump_line
*
ol
=
list_entry
(
entry
,
struct
objdump_line
,
node
);
return
ol
->
offset
==
-
1
;
}
return
false
;
}
static
void
annotate_browser__write
(
struct
ui_browser
*
self
,
void
*
entry
,
int
row
)
{
struct
annotate_browser
*
ab
=
container_of
(
self
,
struct
annotate_browser
,
b
);
struct
objdump_line
*
ol
=
rb
_entry
(
entry
,
struct
objdump_line
,
node
);
struct
objdump_line
*
ol
=
list
_entry
(
entry
,
struct
objdump_line
,
node
);
bool
current_entry
=
ui_browser__is_current_entry
(
self
,
row
);
int
width
=
self
->
width
;
...
...
@@ -168,6 +184,45 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
browser
->
curr_hot
=
rb_last
(
&
browser
->
entries
);
}
static
bool
annotate_browser__toggle_source
(
struct
annotate_browser
*
browser
)
{
struct
objdump_line
*
ol
;
struct
objdump_line_rb_node
*
olrb
;
off_t
offset
=
browser
->
b
.
index
-
browser
->
b
.
top_idx
;
browser
->
b
.
seek
(
&
browser
->
b
,
offset
,
SEEK_CUR
);
ol
=
list_entry
(
browser
->
b
.
top
,
struct
objdump_line
,
node
);
olrb
=
objdump_line__rb
(
ol
);
if
(
browser
->
hide_src_code
)
{
if
(
olrb
->
idx_asm
<
offset
)
offset
=
olrb
->
idx
;
browser
->
b
.
nr_entries
=
browser
->
nr_entries
;
browser
->
hide_src_code
=
false
;
browser
->
b
.
seek
(
&
browser
->
b
,
-
offset
,
SEEK_CUR
);
browser
->
b
.
top_idx
=
olrb
->
idx
-
offset
;
browser
->
b
.
index
=
olrb
->
idx
;
}
else
{
if
(
olrb
->
idx_asm
<
0
)
{
ui_helpline__puts
(
"Only available for assembly lines."
);
browser
->
b
.
seek
(
&
browser
->
b
,
-
offset
,
SEEK_CUR
);
return
false
;
}
if
(
olrb
->
idx_asm
<
offset
)
offset
=
olrb
->
idx_asm
;
browser
->
b
.
nr_entries
=
browser
->
nr_asm_entries
;
browser
->
hide_src_code
=
true
;
browser
->
b
.
seek
(
&
browser
->
b
,
-
offset
,
SEEK_CUR
);
browser
->
b
.
top_idx
=
olrb
->
idx_asm
-
offset
;
browser
->
b
.
index
=
olrb
->
idx_asm
;
}
return
true
;
}
static
int
annotate_browser__run
(
struct
annotate_browser
*
self
,
int
evidx
,
int
nr_events
,
void
(
*
timer
)(
void
*
arg
),
void
*
arg
,
int
delay_secs
)
...
...
@@ -175,20 +230,14 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
struct
rb_node
*
nd
=
NULL
;
struct
map_symbol
*
ms
=
self
->
b
.
priv
;
struct
symbol
*
sym
=
ms
->
sym
;
/*
* RIGHT To allow builtin-annotate to cycle thru multiple symbols by
* examining the exit key for this function.
*/
int
exit_keys
[]
=
{
'H'
,
NEWT_KEY_TAB
,
NEWT_KEY_UNTAB
,
NEWT_KEY_RIGHT
,
NEWT_KEY_ENTER
,
0
};
const
char
*
help
=
"<-, ESC: exit, TAB/shift+TAB: cycle hottest lines, "
"H: Hottest, -> Line action, S -> Toggle source "
"code view"
;
int
key
;
if
(
ui_browser__show
(
&
self
->
b
,
sym
->
name
,
"<- or ESC: exit, TAB/shift+TAB: "
"cycle hottest lines, H: Hottest, -> Line action"
)
<
0
)
if
(
ui_browser__show
(
&
self
->
b
,
sym
->
name
,
help
)
<
0
)
return
-
1
;
ui_browser__add_exit_keys
(
&
self
->
b
,
exit_keys
);
annotate_browser__calc_percent
(
self
,
evidx
);
if
(
self
->
curr_hot
)
...
...
@@ -196,11 +245,8 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
nd
=
self
->
curr_hot
;
if
(
delay_secs
!=
0
)
newtFormSetTimer
(
self
->
b
.
form
,
delay_secs
*
1000
);
while
(
1
)
{
key
=
ui_browser__run
(
&
self
->
b
);
key
=
ui_browser__run
(
&
self
->
b
,
delay_secs
);
if
(
delay_secs
!=
0
)
{
annotate_browser__calc_percent
(
self
,
evidx
);
...
...
@@ -244,6 +290,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
case
'H'
:
nd
=
self
->
curr_hot
;
break
;
case
'S'
:
if
(
annotate_browser__toggle_source
(
self
))
ui_helpline__puts
(
help
);
continue
;
case
NEWT_KEY_ENTER
:
case
NEWT_KEY_RIGHT
:
if
(
self
->
selection
==
NULL
)
{
...
...
@@ -295,8 +345,13 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
timer
,
arg
,
delay_secs
);
}
break
;
default:
case
NEWT_KEY_LEFT
:
case
NEWT_KEY_ESCAPE
:
case
'q'
:
case
CTRL
(
'c'
):
goto
out
;
default:
continue
;
}
if
(
nd
!=
NULL
)
...
...
@@ -329,6 +384,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
.
refresh
=
ui_browser__list_head_refresh
,
.
seek
=
ui_browser__list_head_seek
,
.
write
=
annotate_browser__write
,
.
filter
=
objdump_line__filter
,
.
priv
=
&
ms
,
},
};
...
...
@@ -356,9 +412,14 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
if
(
browser
.
b
.
width
<
line_len
)
browser
.
b
.
width
=
line_len
;
rbpos
=
objdump_line__rb
(
pos
);
rbpos
->
idx
=
browser
.
b
.
nr_entries
++
;
rbpos
->
idx
=
browser
.
nr_entries
++
;
if
(
pos
->
offset
!=
-
1
)
rbpos
->
idx_asm
=
browser
.
nr_asm_entries
++
;
else
rbpos
->
idx_asm
=
-
1
;
}
browser
.
b
.
nr_entries
=
browser
.
nr_entries
;
browser
.
b
.
entries
=
&
notes
->
src
->
source
,
browser
.
b
.
width
+=
18
;
/* Percentage */
ret
=
annotate_browser__run
(
&
browser
,
evidx
,
nr_events
,
...
...
tools/perf/util/ui/browsers/hists.c
浏览文件 @
c73a3cb3
...
...
@@ -301,11 +301,7 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name,
void
(
*
timer
)(
void
*
arg
),
void
*
arg
,
int
delay_secs
)
{
int
key
;
int
delay_msecs
=
delay_secs
*
1000
;
char
title
[
160
];
int
sym_exit_keys
[]
=
{
'a'
,
'h'
,
'C'
,
'd'
,
'E'
,
't'
,
0
,
};
int
exit_keys
[]
=
{
'?'
,
'h'
,
'D'
,
NEWT_KEY_LEFT
,
NEWT_KEY_RIGHT
,
NEWT_KEY_TAB
,
NEWT_KEY_UNTAB
,
NEWT_KEY_ENTER
,
0
,
};
self
->
b
.
entries
=
&
self
->
hists
->
entries
;
self
->
b
.
nr_entries
=
self
->
hists
->
nr_entries
;
...
...
@@ -318,27 +314,14 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name,
"Press '?' for help on key bindings"
)
<
0
)
return
-
1
;
if
(
timer
!=
NULL
)
newtFormSetTimer
(
self
->
b
.
form
,
delay_msecs
);
ui_browser__add_exit_keys
(
&
self
->
b
,
exit_keys
);
if
(
self
->
has_symbols
)
ui_browser__add_exit_keys
(
&
self
->
b
,
sym_exit_keys
);
while
(
1
)
{
key
=
ui_browser__run
(
&
self
->
b
);
key
=
ui_browser__run
(
&
self
->
b
,
delay_secs
);
switch
(
key
)
{
case
-
1
:
/* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
timer
(
arg
);
/*
* The timer may have changed the number of entries.
* XXX: Find better way to keep this in synch, probably
* removing this timer function altogether and just sync
* using the hists->lock...
*/
self
->
b
.
nr_entries
=
self
->
hists
->
nr_entries
;
ui_browser__update_nr_entries
(
&
self
->
b
,
self
->
hists
->
nr_entries
);
hists__browser_title
(
self
->
hists
,
title
,
sizeof
(
title
),
ev_name
,
self
->
dso_filter
,
self
->
thread_filter
);
...
...
@@ -617,14 +600,23 @@ static int hist_browser__show_entry(struct hist_browser *self,
return
printed
;
}
static
void
ui_browser__hists_init_top
(
struct
ui_browser
*
browser
)
{
if
(
browser
->
top
==
NULL
)
{
struct
hist_browser
*
hb
;
hb
=
container_of
(
browser
,
struct
hist_browser
,
b
);
browser
->
top
=
rb_first
(
&
hb
->
hists
->
entries
);
}
}
static
unsigned
int
hist_browser__refresh
(
struct
ui_browser
*
self
)
{
unsigned
row
=
0
;
struct
rb_node
*
nd
;
struct
hist_browser
*
hb
=
container_of
(
self
,
struct
hist_browser
,
b
);
if
(
self
->
top
==
NULL
)
self
->
top
=
rb_first
(
&
hb
->
hists
->
entries
);
ui_browser__hists_init_top
(
self
);
for
(
nd
=
self
->
top
;
nd
;
nd
=
rb_next
(
nd
))
{
struct
hist_entry
*
h
=
rb_entry
(
nd
,
struct
hist_entry
,
rb_node
);
...
...
@@ -676,6 +668,8 @@ static void ui_browser__hists_seek(struct ui_browser *self,
if
(
self
->
nr_entries
==
0
)
return
;
ui_browser__hists_init_top
(
self
);
switch
(
whence
)
{
case
SEEK_SET
:
nd
=
hists__filter_entries
(
rb_first
(
self
->
entries
));
...
...
@@ -931,8 +925,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
!
ui__dialog_yesno
(
"Do you really want to exit?"
))
continue
;
/* Fall thru */
default:
case
'q'
:
case
CTRL
(
'c'
):
goto
out_free_stack
;
default:
continue
;
}
if
(
!
browser
->
has_symbols
)
...
...
@@ -982,9 +979,14 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
he
=
hist_browser__selected_entry
(
browser
);
if
(
he
==
NULL
)
continue
;
/*
* Don't let this be freed, say, by hists__decay_entry.
*/
he
->
used
=
true
;
hist_entry__tui_annotate
(
he
,
evsel
->
idx
,
nr_events
,
timer
,
arg
,
delay_secs
);
he
->
used
=
false
;
ui_browser__update_nr_entries
(
&
browser
->
b
,
browser
->
hists
->
nr_entries
);
}
else
if
(
choice
==
browse_map
)
map__browse
(
browser
->
selection
->
map
);
else
if
(
choice
==
zoom_dso
)
{
...
...
@@ -1061,8 +1063,6 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
int
nr_events
,
const
char
*
help
,
void
(
*
timer
)(
void
*
arg
),
void
*
arg
,
int
delay_secs
)
{
int
exit_keys
[]
=
{
NEWT_KEY_ENTER
,
NEWT_KEY_RIGHT
,
0
,
};
int
delay_msecs
=
delay_secs
*
1000
;
struct
perf_evlist
*
evlist
=
menu
->
b
.
priv
;
struct
perf_evsel
*
pos
;
const
char
*
ev_name
,
*
title
=
"Available samples"
;
...
...
@@ -1072,13 +1072,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
"ESC: exit, ENTER|->: Browse histograms"
)
<
0
)
return
-
1
;
if
(
timer
!=
NULL
)
newtFormSetTimer
(
menu
->
b
.
form
,
delay_msecs
);
ui_browser__add_exit_keys
(
&
menu
->
b
,
exit_keys
);
while
(
1
)
{
key
=
ui_browser__run
(
&
menu
->
b
);
key
=
ui_browser__run
(
&
menu
->
b
,
delay_secs
);
switch
(
key
)
{
case
-
1
:
...
...
@@ -1090,44 +1085,53 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
if
(
!
menu
->
selection
)
continue
;
pos
=
menu
->
selection
;
perf_evlist__set_selected
(
evlist
,
pos
);
browse_hists:
perf_evlist__set_selected
(
evlist
,
pos
);
/*
* Give the calling tool a chance to populate the non
* default evsel resorted hists tree.
*/
if
(
timer
)
timer
(
arg
);
ev_name
=
event_name
(
pos
);
key
=
perf_evsel__hists_browse
(
pos
,
nr_events
,
help
,
ev_name
,
true
,
timer
,
arg
,
delay_secs
);
ui_browser__show_title
(
&
menu
->
b
,
title
);
break
;
switch
(
key
)
{
case
NEWT_KEY_TAB
:
if
(
pos
->
node
.
next
==
&
evlist
->
entries
)
pos
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
else
pos
=
list_entry
(
pos
->
node
.
next
,
struct
perf_evsel
,
node
);
goto
browse_hists
;
case
NEWT_KEY_UNTAB
:
if
(
pos
->
node
.
prev
==
&
evlist
->
entries
)
pos
=
list_entry
(
evlist
->
entries
.
prev
,
struct
perf_evsel
,
node
);
else
pos
=
list_entry
(
pos
->
node
.
prev
,
struct
perf_evsel
,
node
);
goto
browse_hists
;
case
NEWT_KEY_ESCAPE
:
if
(
!
ui__dialog_yesno
(
"Do you really want to exit?"
))
continue
;
/* Fall thru */
case
'q'
:
case
CTRL
(
'c'
):
goto
out
;
default:
continue
;
}
case
NEWT_KEY_LEFT
:
continue
;
case
NEWT_KEY_ESCAPE
:
if
(
!
ui__dialog_yesno
(
"Do you really want to exit?"
))
continue
;
/* Fall thru */
default:
goto
out
;
}
switch
(
key
)
{
case
NEWT_KEY_TAB
:
if
(
pos
->
node
.
next
==
&
evlist
->
entries
)
pos
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
else
pos
=
list_entry
(
pos
->
node
.
next
,
struct
perf_evsel
,
node
);
perf_evlist__set_selected
(
evlist
,
pos
);
goto
browse_hists
;
case
NEWT_KEY_UNTAB
:
if
(
pos
->
node
.
prev
==
&
evlist
->
entries
)
pos
=
list_entry
(
evlist
->
entries
.
prev
,
struct
perf_evsel
,
node
);
else
pos
=
list_entry
(
pos
->
node
.
prev
,
struct
perf_evsel
,
node
);
perf_evlist__set_selected
(
evlist
,
pos
);
goto
browse_hists
;
case
'q'
:
case
CTRL
(
'c'
):
goto
out
;
default:
break
;
continue
;
}
}
...
...
tools/perf/util/ui/browsers/map.c
浏览文件 @
c73a3cb3
#include "../libslang.h"
#include <elf.h>
#include <newt.h>
#include <inttypes.h>
#include <sys/ttydefaults.h>
#include <ctype.h>
...
...
@@ -108,11 +109,8 @@ static int map_browser__run(struct map_browser *self)
verbose
?
""
:
"restart with -v to use"
)
<
0
)
return
-
1
;
if
(
verbose
)
ui_browser__add_exit_key
(
&
self
->
b
,
'/'
);
while
(
1
)
{
key
=
ui_browser__run
(
&
self
->
b
);
key
=
ui_browser__run
(
&
self
->
b
,
0
);
if
(
verbose
&&
key
==
'/'
)
map_browser__search
(
self
);
...
...
tools/perf/util/ui/helpline.h
浏览文件 @
c73a3cb3
#ifndef _PERF_UI_HELPLINE_H_
#define _PERF_UI_HELPLINE_H_ 1
#include <stdio.h>
void
ui_helpline__init
(
void
);
void
ui_helpline__pop
(
void
);
void
ui_helpline__push
(
const
char
*
msg
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录