Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 269047
b: refs/heads/master
c: 19d4ac3
h: refs/heads/master
i:
  269045: 921a1cc
  269043: befdbc7
  269039: c4de203
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo committed Oct 7, 2011
1 parent 6925437 commit a3e93f6
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ab81f3fd350c510730adb1ca40ef55c2b2952121
refs/heads/master: 19d4ac3c1039fb952f4c073fd0898e9295a836c8
15 changes: 15 additions & 0 deletions trunk/tools/perf/Documentation/perf-top.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@ Default is to monitor all CPUS.
--symbols::
Only consider these symbols.

-G [type,min,order]::
--call-graph::
Display call chains using type, min percent threshold and order.
type can be either:
- flat: single column, linear exposure of call chains.
- graph: use a graph tree, displaying absolute overhead rates.
- fractal: like graph, but displays relative rates. Each branch of
the tree is considered as a new profiled object.

order can be either:
- callee: callee based call graph.
- caller: inverted caller based call graph.

Default: fractal,0.5,callee.

INTERACTIVE PROMPTING KEYS
--------------------------

Expand Down
146 changes: 144 additions & 2 deletions trunk/tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ static bool system_wide = false;

static bool use_tui, use_stdio;

static bool sort_has_symbols;

static bool dont_use_callchains;
static char callchain_default_opt[] = "fractal,0.5,callee";


static int default_interval = 0;

static bool kptr_restrict_warned;
Expand Down Expand Up @@ -648,9 +654,11 @@ static void perf_event__process_sample(const union perf_event *event,
struct perf_sample *sample,
struct perf_session *session)
{
struct symbol *parent = NULL;
u64 ip = event->ip.ip;
struct addr_location al;
struct machine *machine;
int err;
u8 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;

++top.samples;
Expand Down Expand Up @@ -748,13 +756,29 @@ static void perf_event__process_sample(const union perf_event *event,
evsel = perf_evlist__id2evsel(top.evlist, sample->id);
assert(evsel != NULL);

if ((sort__has_parent || symbol_conf.use_callchain) &&
sample->callchain) {
err = perf_session__resolve_callchain(session, al.thread,
sample->callchain, &parent);
if (err)
return;
}

he = perf_session__add_hist_entry(session, &al, sample, evsel);
if (he == NULL) {
pr_err("Problem incrementing symbol period, skipping event\n");
return;
}

record_precise_ip(he, evsel->idx, ip);
if (symbol_conf.use_callchain) {
err = callchain_append(he->callchain, &session->callchain_cursor,
sample->period);
if (err)
return;
}

if (sort_has_symbols)
record_precise_ip(he, evsel->idx, ip);
}

return;
Expand Down Expand Up @@ -808,6 +832,9 @@ static void start_counters(struct perf_evlist *evlist)
attr->read_format |= PERF_FORMAT_ID;
}

if (symbol_conf.use_callchain)
attr->sample_type |= PERF_SAMPLE_CALLCHAIN;

attr->mmap = 1;
attr->comm = 1;
attr->inherit = inherit;
Expand Down Expand Up @@ -864,10 +891,27 @@ static void start_counters(struct perf_evlist *evlist)
exit(0);
}

static int setup_sample_type(void)
{
if (!sort_has_symbols) {
if (symbol_conf.use_callchain) {
ui__warning("Selected -g but \"sym\" not present in --sort/-s.");
return -EINVAL;
}
} else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE) {
if (callchain_register_param(&callchain_param) < 0) {
ui__warning("Can't register callchain params.\n");
return -EINVAL;
}
}

return 0;
}

static int __cmd_top(void)
{
pthread_t thread;
int ret __used;
int ret;
/*
* FIXME: perf_session__new should allow passing a O_MMAP, so that all this
* mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
Expand All @@ -876,6 +920,10 @@ static int __cmd_top(void)
if (top.session == NULL)
return -ENOMEM;

ret = setup_sample_type();
if (ret)
goto out_delete;

if (top.target_tid != -1)
perf_event__synthesize_thread_map(top.evlist->threads,
perf_event__process, top.session);
Expand Down Expand Up @@ -916,6 +964,90 @@ static int __cmd_top(void)
ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
}

out_delete:
perf_session__delete(top.session);
top.session = NULL;

return 0;
}

static int
parse_callchain_opt(const struct option *opt __used, const char *arg,
int unset)
{
char *tok, *tok2;
char *endptr;

/*
* --no-call-graph
*/
if (unset) {
dont_use_callchains = true;
return 0;
}

symbol_conf.use_callchain = true;

if (!arg)
return 0;

tok = strtok((char *)arg, ",");
if (!tok)
return -1;

/* get the output mode */
if (!strncmp(tok, "graph", strlen(arg)))
callchain_param.mode = CHAIN_GRAPH_ABS;

else if (!strncmp(tok, "flat", strlen(arg)))
callchain_param.mode = CHAIN_FLAT;

else if (!strncmp(tok, "fractal", strlen(arg)))
callchain_param.mode = CHAIN_GRAPH_REL;

else if (!strncmp(tok, "none", strlen(arg))) {
callchain_param.mode = CHAIN_NONE;
symbol_conf.use_callchain = false;

return 0;
}

else
return -1;

/* get the min percentage */
tok = strtok(NULL, ",");
if (!tok)
goto setup;

callchain_param.min_percent = strtod(tok, &endptr);
if (tok == endptr)
return -1;

/* get the print limit */
tok2 = strtok(NULL, ",");
if (!tok2)
goto setup;

if (tok2[0] != 'c') {
callchain_param.print_limit = strtod(tok2, &endptr);
tok2 = strtok(NULL, ",");
if (!tok2)
goto setup;
}

/* get the call chain order */
if (!strcmp(tok2, "caller"))
callchain_param.order = ORDER_CALLER;
else if (!strcmp(tok2, "callee"))
callchain_param.order = ORDER_CALLEE;
else
return -1;
setup:
if (callchain_register_param(&callchain_param) < 0) {
fprintf(stderr, "Can't register callchain params\n");
return -1;
}
return 0;
}

Expand Down Expand Up @@ -973,6 +1105,10 @@ static const struct option options[] = {
"sort by key(s): pid, comm, dso, symbol, parent"),
OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
"Show a column with the number of samples"),
OPT_CALLBACK_DEFAULT('G', "call-graph", NULL, "output_type,min_percent, call_order",
"Display callchains using output_type (graph, flat, fractal, or none), min percent threshold and callchain order. "
"Default: fractal,0.5,callee", &parse_callchain_opt,
callchain_default_opt),
OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
"Show a column with the sum of periods"),
OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
Expand Down Expand Up @@ -1082,6 +1218,12 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);

/*
* Avoid annotation data structures overhead when symbols aren't on the
* sort list.
*/
sort_has_symbols = sort_sym.list.next != NULL;

get_term_dimensions(&winsize);
if (top.print_entries == 0) {
update_print_entries(&winsize);
Expand Down

0 comments on commit a3e93f6

Please sign in to comment.