mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into perf/core
This commit is contained in:
commit
343a031f3c
7 changed files with 169 additions and 144 deletions
|
@ -80,15 +80,24 @@ OPTIONS
|
||||||
--dump-raw-trace::
|
--dump-raw-trace::
|
||||||
Dump raw trace in ASCII.
|
Dump raw trace in ASCII.
|
||||||
|
|
||||||
-g [type,min]::
|
-g [type,min,order]::
|
||||||
--call-graph::
|
--call-graph::
|
||||||
Display call chains using type and min percent threshold.
|
Display call chains using type, min percent threshold and order.
|
||||||
type can be either:
|
type can be either:
|
||||||
- flat: single column, linear exposure of call chains.
|
- flat: single column, linear exposure of call chains.
|
||||||
- graph: use a graph tree, displaying absolute overhead rates.
|
- graph: use a graph tree, displaying absolute overhead rates.
|
||||||
- fractal: like graph, but displays relative rates. Each branch of
|
- fractal: like graph, but displays relative rates. Each branch of
|
||||||
the tree is considered as a new profiled object. +
|
the tree is considered as a new profiled object. +
|
||||||
Default: fractal,0.5.
|
|
||||||
|
order can be either:
|
||||||
|
- callee: callee based call graph.
|
||||||
|
- caller: inverted caller based call graph.
|
||||||
|
|
||||||
|
Default: fractal,0.5,callee.
|
||||||
|
|
||||||
|
-G::
|
||||||
|
--inverted::
|
||||||
|
alias for inverted caller based call graph.
|
||||||
|
|
||||||
--pretty=<key>::
|
--pretty=<key>::
|
||||||
Pretty printing style. key: normal, raw
|
Pretty printing style. key: normal, raw
|
||||||
|
|
|
@ -45,7 +45,8 @@ static struct perf_read_values show_threads_values;
|
||||||
static const char default_pretty_printing_style[] = "normal";
|
static const char default_pretty_printing_style[] = "normal";
|
||||||
static const char *pretty_printing_style = default_pretty_printing_style;
|
static const char *pretty_printing_style = default_pretty_printing_style;
|
||||||
|
|
||||||
static char callchain_default_opt[] = "fractal,0.5";
|
static char callchain_default_opt[] = "fractal,0.5,callee";
|
||||||
|
static bool inverted_callchain;
|
||||||
static symbol_filter_t annotate_init;
|
static symbol_filter_t annotate_init;
|
||||||
|
|
||||||
static int perf_session__add_hist_entry(struct perf_session *session,
|
static int perf_session__add_hist_entry(struct perf_session *session,
|
||||||
|
@ -386,13 +387,29 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
|
||||||
if (!tok)
|
if (!tok)
|
||||||
goto setup;
|
goto setup;
|
||||||
|
|
||||||
tok2 = strtok(NULL, ",");
|
|
||||||
callchain_param.min_percent = strtod(tok, &endptr);
|
callchain_param.min_percent = strtod(tok, &endptr);
|
||||||
if (tok == endptr)
|
if (tok == endptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (tok2)
|
/* get the print limit */
|
||||||
|
tok2 = strtok(NULL, ",");
|
||||||
|
if (!tok2)
|
||||||
|
goto setup;
|
||||||
|
|
||||||
|
if (tok2[0] != 'c') {
|
||||||
callchain_param.print_limit = strtod(tok2, &endptr);
|
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:
|
setup:
|
||||||
if (callchain_register_param(&callchain_param) < 0) {
|
if (callchain_register_param(&callchain_param) < 0) {
|
||||||
fprintf(stderr, "Can't register callchain params\n");
|
fprintf(stderr, "Can't register callchain params\n");
|
||||||
|
@ -436,9 +453,10 @@ static const struct option options[] = {
|
||||||
"regex filter to identify parent, see: '--sort parent'"),
|
"regex filter to identify parent, see: '--sort parent'"),
|
||||||
OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
|
OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
|
||||||
"Only display entries with parent-match"),
|
"Only display entries with parent-match"),
|
||||||
OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
|
OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order",
|
||||||
"Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. "
|
"Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. "
|
||||||
"Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
|
"Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
|
||||||
|
OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"),
|
||||||
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
|
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
|
||||||
"only consider symbols in these dsos"),
|
"only consider symbols in these dsos"),
|
||||||
OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
|
OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
|
||||||
|
@ -467,6 +485,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
|
||||||
else if (use_tui)
|
else if (use_tui)
|
||||||
use_browser = 1;
|
use_browser = 1;
|
||||||
|
|
||||||
|
if (inverted_callchain)
|
||||||
|
callchain_param.order = ORDER_CALLER;
|
||||||
|
|
||||||
if (strcmp(input_name, "-") != 0)
|
if (strcmp(input_name, "-") != 0)
|
||||||
setup_browser(true);
|
setup_browser(true);
|
||||||
else
|
else
|
||||||
|
@ -504,6 +525,13 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
|
||||||
if (parent_pattern != default_parent_pattern) {
|
if (parent_pattern != default_parent_pattern) {
|
||||||
if (sort_dimension__add("parent") < 0)
|
if (sort_dimension__add("parent") < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only show the parent fields if we explicitly
|
||||||
|
* sort that way. If we only use parent machinery
|
||||||
|
* for filtering, we don't want it.
|
||||||
|
*/
|
||||||
|
if (!strstr(sort_order, "parent"))
|
||||||
sort_parent.elide = 1;
|
sort_parent.elide = 1;
|
||||||
} else
|
} else
|
||||||
symbol_conf.exclude_other = false;
|
symbol_conf.exclude_other = false;
|
||||||
|
|
|
@ -14,6 +14,11 @@ enum chain_mode {
|
||||||
CHAIN_GRAPH_REL
|
CHAIN_GRAPH_REL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum chain_order {
|
||||||
|
ORDER_CALLER,
|
||||||
|
ORDER_CALLEE
|
||||||
|
};
|
||||||
|
|
||||||
struct callchain_node {
|
struct callchain_node {
|
||||||
struct callchain_node *parent;
|
struct callchain_node *parent;
|
||||||
struct list_head siblings;
|
struct list_head siblings;
|
||||||
|
@ -41,6 +46,7 @@ struct callchain_param {
|
||||||
u32 print_limit;
|
u32 print_limit;
|
||||||
double min_percent;
|
double min_percent;
|
||||||
sort_chain_func_t sort;
|
sort_chain_func_t sort;
|
||||||
|
enum chain_order order;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct callchain_list {
|
struct callchain_list {
|
||||||
|
|
|
@ -14,7 +14,8 @@ enum hist_filter {
|
||||||
|
|
||||||
struct callchain_param callchain_param = {
|
struct callchain_param callchain_param = {
|
||||||
.mode = CHAIN_GRAPH_REL,
|
.mode = CHAIN_GRAPH_REL,
|
||||||
.min_percent = 0.5
|
.min_percent = 0.5,
|
||||||
|
.order = ORDER_CALLEE
|
||||||
};
|
};
|
||||||
|
|
||||||
u16 hists__col_len(struct hists *self, enum hist_column col)
|
u16 hists__col_len(struct hists *self, enum hist_column col)
|
||||||
|
@ -846,6 +847,9 @@ print_entries:
|
||||||
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
|
||||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
|
|
||||||
|
if (h->filtered)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (show_displacement) {
|
if (show_displacement) {
|
||||||
if (h->pair != NULL)
|
if (h->pair != NULL)
|
||||||
displacement = ((long)h->pair->position -
|
displacement = ((long)h->pair->position -
|
||||||
|
|
|
@ -247,9 +247,14 @@ int perf_session__resolve_callchain(struct perf_session *self,
|
||||||
callchain_cursor_reset(&self->callchain_cursor);
|
callchain_cursor_reset(&self->callchain_cursor);
|
||||||
|
|
||||||
for (i = 0; i < chain->nr; i++) {
|
for (i = 0; i < chain->nr; i++) {
|
||||||
u64 ip = chain->ips[i];
|
u64 ip;
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
|
|
||||||
|
if (callchain_param.order == ORDER_CALLEE)
|
||||||
|
ip = chain->ips[i];
|
||||||
|
else
|
||||||
|
ip = chain->ips[chain->nr - i - 1];
|
||||||
|
|
||||||
if (ip >= PERF_CONTEXT_MAX) {
|
if (ip >= PERF_CONTEXT_MAX) {
|
||||||
switch (ip) {
|
switch (ip) {
|
||||||
case PERF_CONTEXT_HV:
|
case PERF_CONTEXT_HV:
|
||||||
|
|
|
@ -15,95 +15,6 @@ char * field_sep;
|
||||||
|
|
||||||
LIST_HEAD(hist_entry__sort_list);
|
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);
|
|
||||||
static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
|
|
||||||
size_t size, unsigned int width);
|
|
||||||
|
|
||||||
struct sort_entry sort_thread = {
|
|
||||||
.se_header = "Command: Pid",
|
|
||||||
.se_cmp = sort__thread_cmp,
|
|
||||||
.se_snprintf = hist_entry__thread_snprintf,
|
|
||||||
.se_width_idx = HISTC_THREAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sort_entry sort_comm = {
|
|
||||||
.se_header = "Command",
|
|
||||||
.se_cmp = sort__comm_cmp,
|
|
||||||
.se_collapse = sort__comm_collapse,
|
|
||||||
.se_snprintf = hist_entry__comm_snprintf,
|
|
||||||
.se_width_idx = HISTC_COMM,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sort_entry sort_dso = {
|
|
||||||
.se_header = "Shared Object",
|
|
||||||
.se_cmp = sort__dso_cmp,
|
|
||||||
.se_snprintf = hist_entry__dso_snprintf,
|
|
||||||
.se_width_idx = HISTC_DSO,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sort_entry sort_sym = {
|
|
||||||
.se_header = "Symbol",
|
|
||||||
.se_cmp = sort__sym_cmp,
|
|
||||||
.se_snprintf = hist_entry__sym_snprintf,
|
|
||||||
.se_width_idx = HISTC_SYMBOL,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sort_entry sort_parent = {
|
|
||||||
.se_header = "Parent symbol",
|
|
||||||
.se_cmp = sort__parent_cmp,
|
|
||||||
.se_snprintf = hist_entry__parent_snprintf,
|
|
||||||
.se_width_idx = HISTC_PARENT,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sort_entry sort_cpu = {
|
|
||||||
.se_header = "CPU",
|
|
||||||
.se_cmp = sort__cpu_cmp,
|
|
||||||
.se_snprintf = hist_entry__cpu_snprintf,
|
|
||||||
.se_width_idx = HISTC_CPU,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sort_dimension {
|
|
||||||
const char *name;
|
|
||||||
struct sort_entry *entry;
|
|
||||||
int taken;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sort_dimension sort_dimensions[] = {
|
|
||||||
{ .name = "pid", .entry = &sort_thread, },
|
|
||||||
{ .name = "comm", .entry = &sort_comm, },
|
|
||||||
{ .name = "dso", .entry = &sort_dso, },
|
|
||||||
{ .name = "symbol", .entry = &sort_sym, },
|
|
||||||
{ .name = "parent", .entry = &sort_parent, },
|
|
||||||
{ .name = "cpu", .entry = &sort_cpu, },
|
|
||||||
};
|
|
||||||
|
|
||||||
int64_t cmp_null(void *l, void *r)
|
|
||||||
{
|
|
||||||
if (!l && !r)
|
|
||||||
return 0;
|
|
||||||
else if (!l)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --sort pid */
|
|
||||||
|
|
||||||
int64_t
|
|
||||||
sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
|
|
||||||
{
|
|
||||||
return right->thread->pid - left->thread->pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
@ -125,6 +36,24 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64_t cmp_null(void *l, void *r)
|
||||||
|
{
|
||||||
|
if (!l && !r)
|
||||||
|
return 0;
|
||||||
|
else if (!l)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --sort pid */
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
|
{
|
||||||
|
return right->thread->pid - left->thread->pid;
|
||||||
|
}
|
||||||
|
|
||||||
static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
||||||
size_t size, unsigned int width)
|
size_t size, unsigned int width)
|
||||||
{
|
{
|
||||||
|
@ -132,15 +61,50 @@ static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
|
||||||
self->thread->comm ?: "", self->thread->pid);
|
self->thread->comm ?: "", self->thread->pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sort_entry sort_thread = {
|
||||||
|
.se_header = "Command: Pid",
|
||||||
|
.se_cmp = sort__thread_cmp,
|
||||||
|
.se_snprintf = hist_entry__thread_snprintf,
|
||||||
|
.se_width_idx = HISTC_THREAD,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --sort comm */
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
|
{
|
||||||
|
return right->thread->pid - left->thread->pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
|
||||||
|
{
|
||||||
|
char *comm_l = left->thread->comm;
|
||||||
|
char *comm_r = right->thread->comm;
|
||||||
|
|
||||||
|
if (!comm_l || !comm_r)
|
||||||
|
return cmp_null(comm_l, comm_r);
|
||||||
|
|
||||||
|
return strcmp(comm_l, comm_r);
|
||||||
|
}
|
||||||
|
|
||||||
static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
|
static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
|
||||||
size_t size, unsigned int width)
|
size_t size, unsigned int width)
|
||||||
{
|
{
|
||||||
return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
|
return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sort_entry sort_comm = {
|
||||||
|
.se_header = "Command",
|
||||||
|
.se_cmp = sort__comm_cmp,
|
||||||
|
.se_collapse = sort__comm_collapse,
|
||||||
|
.se_snprintf = hist_entry__comm_snprintf,
|
||||||
|
.se_width_idx = HISTC_COMM,
|
||||||
|
};
|
||||||
|
|
||||||
/* --sort dso */
|
/* --sort dso */
|
||||||
|
|
||||||
int64_t
|
static int64_t
|
||||||
sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
|
sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
{
|
{
|
||||||
struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
|
struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
|
||||||
|
@ -173,9 +137,16 @@ static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
|
||||||
return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
|
return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sort_entry sort_dso = {
|
||||||
|
.se_header = "Shared Object",
|
||||||
|
.se_cmp = sort__dso_cmp,
|
||||||
|
.se_snprintf = hist_entry__dso_snprintf,
|
||||||
|
.se_width_idx = HISTC_DSO,
|
||||||
|
};
|
||||||
|
|
||||||
/* --sort symbol */
|
/* --sort symbol */
|
||||||
|
|
||||||
int64_t
|
static int64_t
|
||||||
sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
|
sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
{
|
{
|
||||||
u64 ip_l, ip_r;
|
u64 ip_l, ip_r;
|
||||||
|
@ -211,29 +182,16 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --sort comm */
|
struct sort_entry sort_sym = {
|
||||||
|
.se_header = "Symbol",
|
||||||
int64_t
|
.se_cmp = sort__sym_cmp,
|
||||||
sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
|
.se_snprintf = hist_entry__sym_snprintf,
|
||||||
{
|
.se_width_idx = HISTC_SYMBOL,
|
||||||
return right->thread->pid - left->thread->pid;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
int64_t
|
|
||||||
sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
|
|
||||||
{
|
|
||||||
char *comm_l = left->thread->comm;
|
|
||||||
char *comm_r = right->thread->comm;
|
|
||||||
|
|
||||||
if (!comm_l || !comm_r)
|
|
||||||
return cmp_null(comm_l, comm_r);
|
|
||||||
|
|
||||||
return strcmp(comm_l, comm_r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --sort parent */
|
/* --sort parent */
|
||||||
|
|
||||||
int64_t
|
static int64_t
|
||||||
sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
|
sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
{
|
{
|
||||||
struct symbol *sym_l = left->parent;
|
struct symbol *sym_l = left->parent;
|
||||||
|
@ -252,9 +210,16 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
|
||||||
self->parent ? self->parent->name : "[other]");
|
self->parent ? self->parent->name : "[other]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sort_entry sort_parent = {
|
||||||
|
.se_header = "Parent symbol",
|
||||||
|
.se_cmp = sort__parent_cmp,
|
||||||
|
.se_snprintf = hist_entry__parent_snprintf,
|
||||||
|
.se_width_idx = HISTC_PARENT,
|
||||||
|
};
|
||||||
|
|
||||||
/* --sort cpu */
|
/* --sort cpu */
|
||||||
|
|
||||||
int64_t
|
static int64_t
|
||||||
sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
|
sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||||
{
|
{
|
||||||
return right->cpu - left->cpu;
|
return right->cpu - left->cpu;
|
||||||
|
@ -266,6 +231,28 @@ static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
|
||||||
return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
|
return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sort_entry sort_cpu = {
|
||||||
|
.se_header = "CPU",
|
||||||
|
.se_cmp = sort__cpu_cmp,
|
||||||
|
.se_snprintf = hist_entry__cpu_snprintf,
|
||||||
|
.se_width_idx = HISTC_CPU,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sort_dimension {
|
||||||
|
const char *name;
|
||||||
|
struct sort_entry *entry;
|
||||||
|
int taken;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sort_dimension sort_dimensions[] = {
|
||||||
|
{ .name = "pid", .entry = &sort_thread, },
|
||||||
|
{ .name = "comm", .entry = &sort_comm, },
|
||||||
|
{ .name = "dso", .entry = &sort_dso, },
|
||||||
|
{ .name = "symbol", .entry = &sort_sym, },
|
||||||
|
{ .name = "parent", .entry = &sort_parent, },
|
||||||
|
{ .name = "cpu", .entry = &sort_cpu, },
|
||||||
|
};
|
||||||
|
|
||||||
int sort_dimension__add(const char *tok)
|
int sort_dimension__add(const char *tok)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -273,15 +260,9 @@ int sort_dimension__add(const char *tok)
|
||||||
for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
|
for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
|
||||||
struct sort_dimension *sd = &sort_dimensions[i];
|
struct sort_dimension *sd = &sort_dimensions[i];
|
||||||
|
|
||||||
if (sd->taken)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strncasecmp(tok, sd->name, strlen(tok)))
|
if (strncasecmp(tok, sd->name, strlen(tok)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sd->entry->se_collapse)
|
|
||||||
sort__need_collapse = 1;
|
|
||||||
|
|
||||||
if (sd->entry == &sort_parent) {
|
if (sd->entry == &sort_parent) {
|
||||||
int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
|
int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -294,6 +275,12 @@ int sort_dimension__add(const char *tok)
|
||||||
sort__has_parent = 1;
|
sort__has_parent = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sd->taken)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sd->entry->se_collapse)
|
||||||
|
sort__need_collapse = 1;
|
||||||
|
|
||||||
if (list_empty(&hist_entry__sort_list)) {
|
if (list_empty(&hist_entry__sort_list)) {
|
||||||
if (!strcmp(sd->name, "pid"))
|
if (!strcmp(sd->name, "pid"))
|
||||||
sort__first_dimension = SORT_PID;
|
sort__first_dimension = SORT_PID;
|
||||||
|
|
|
@ -103,20 +103,6 @@ extern struct sort_entry sort_thread;
|
||||||
extern struct list_head hist_entry__sort_list;
|
extern struct list_head hist_entry__sort_list;
|
||||||
|
|
||||||
void setup_sorting(const char * const usagestr[], const struct option *opts);
|
void setup_sorting(const char * const usagestr[], const struct option *opts);
|
||||||
|
|
||||||
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);
|
|
||||||
extern size_t sort__sym_print(FILE *, struct hist_entry *, unsigned int __used);
|
|
||||||
extern int64_t cmp_null(void *, void *);
|
|
||||||
extern int64_t sort__thread_cmp(struct hist_entry *, struct hist_entry *);
|
|
||||||
extern int64_t sort__comm_cmp(struct hist_entry *, struct hist_entry *);
|
|
||||||
extern int64_t sort__comm_collapse(struct hist_entry *, struct hist_entry *);
|
|
||||||
extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *);
|
|
||||||
extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *);
|
|
||||||
extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *);
|
|
||||||
int64_t sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right);
|
|
||||||
extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int);
|
|
||||||
extern int sort_dimension__add(const char *);
|
extern int sort_dimension__add(const char *);
|
||||||
void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
|
void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
|
||||||
const char *list_name, FILE *fp);
|
const char *list_name, FILE *fp);
|
||||||
|
|
Loading…
Reference in a new issue