perf report: Add -F option to specify output fields
The -F/--fields option is to allow user setup output field in any order. It can receive any sort keys and following (hpp) fields: overhead, overhead_sys, overhead_us, sample and period If guest profiling is enabled, overhead_guest_{sys,us} will be available too. The output fields also affect sort order unless you give -s/--sort option. And any keys specified on -s option, will also be added to the output field list automatically. $ perf report -F sym,sample,overhead ... # Symbol Samples Overhead # .......................... ............ ........ # [.] __cxa_atexit 2 2.50% [.] __libc_csu_init 4 5.00% [.] __new_exitfn 3 3.75% [.] _dl_check_map_versions 1 1.25% [.] _dl_name_match_p 4 5.00% [.] _dl_setup_hash 1 1.25% [.] _dl_sysdep_start 1 1.25% [.] _init 5 6.25% [.] _setjmp 6 7.50% [.] a 8 10.00% [.] b 8 10.00% [.] brk 1 1.25% [.] c 8 10.00% Note that, the example output above is captured after applying next patch which fixes sort/comparing behavior. Requested-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Acked-by: Ingo Molnar <mingo@kernel.org> Link: http://lkml.kernel.org/r/1400480762-22852-12-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org>
This commit is contained in:
parent
22af969e8c
commit
a7d945bc91
6 changed files with 282 additions and 17 deletions
|
@ -107,6 +107,16 @@ OPTIONS
|
||||||
And default sort keys are changed to comm, dso_from, symbol_from, dso_to
|
And default sort keys are changed to comm, dso_from, symbol_from, dso_to
|
||||||
and symbol_to, see '--branch-stack'.
|
and symbol_to, see '--branch-stack'.
|
||||||
|
|
||||||
|
-F::
|
||||||
|
--fields=::
|
||||||
|
Specify output field - multiple keys can be specified in CSV format.
|
||||||
|
Following fields are available:
|
||||||
|
overhead, overhead_sys, overhead_us, sample and period.
|
||||||
|
Also it can contain any sort key(s).
|
||||||
|
|
||||||
|
By default, every sort keys not specified in -F will be appended
|
||||||
|
automatically.
|
||||||
|
|
||||||
-p::
|
-p::
|
||||||
--parent=<regex>::
|
--parent=<regex>::
|
||||||
A regex filter to identify parent. The parent is a caller of this
|
A regex filter to identify parent. The parent is a caller of this
|
||||||
|
|
|
@ -701,6 +701,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
|
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
|
||||||
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
|
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
|
||||||
" Please refer the man page for the complete list."),
|
" Please refer the man page for the complete list."),
|
||||||
|
OPT_STRING('F', "fields", &field_order, "key[,keys...]",
|
||||||
|
"output field(s): overhead, period, sample plus all of sort keys"),
|
||||||
OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
|
OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
|
||||||
"Show sample percentage for different cpu modes"),
|
"Show sample percentage for different cpu modes"),
|
||||||
OPT_STRING('p', "parent", &parent_pattern, "regex",
|
OPT_STRING('p', "parent", &parent_pattern, "regex",
|
||||||
|
@ -814,17 +816,14 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setup_sorting() < 0) {
|
if (setup_sorting() < 0) {
|
||||||
parse_options_usage(report_usage, options, "s", 1);
|
if (sort_order)
|
||||||
|
parse_options_usage(report_usage, options, "s", 1);
|
||||||
|
if (field_order)
|
||||||
|
parse_options_usage(sort_order ? NULL : report_usage,
|
||||||
|
options, "F", 1);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent_pattern != default_parent_pattern) {
|
|
||||||
if (sort_dimension__add("parent") < 0)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
perf_hpp__init();
|
|
||||||
|
|
||||||
/* Force tty output for header output. */
|
/* Force tty output for header output. */
|
||||||
if (report.header || report.header_only)
|
if (report.header || report.header_only)
|
||||||
use_browser = 0;
|
use_browser = 0;
|
||||||
|
|
|
@ -355,6 +355,12 @@ void perf_hpp__init(void)
|
||||||
INIT_LIST_HEAD(&fmt->sort_list);
|
INIT_LIST_HEAD(&fmt->sort_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If user specified field order, no need to setup default fields.
|
||||||
|
*/
|
||||||
|
if (field_order)
|
||||||
|
return;
|
||||||
|
|
||||||
perf_hpp__column_enable(PERF_HPP__OVERHEAD);
|
perf_hpp__column_enable(PERF_HPP__OVERHEAD);
|
||||||
|
|
||||||
if (symbol_conf.show_cpu_utilization) {
|
if (symbol_conf.show_cpu_utilization) {
|
||||||
|
@ -377,8 +383,6 @@ void perf_hpp__init(void)
|
||||||
list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
|
list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
|
||||||
if (list_empty(list))
|
if (list_empty(list))
|
||||||
list_add(list, &perf_hpp__sort_list);
|
list_add(list, &perf_hpp__sort_list);
|
||||||
|
|
||||||
perf_hpp__setup_output_field();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void perf_hpp__column_register(struct perf_hpp_fmt *format)
|
void perf_hpp__column_register(struct perf_hpp_fmt *format)
|
||||||
|
@ -403,8 +407,55 @@ void perf_hpp__setup_output_field(void)
|
||||||
|
|
||||||
/* append sort keys to output field */
|
/* append sort keys to output field */
|
||||||
perf_hpp__for_each_sort_list(fmt) {
|
perf_hpp__for_each_sort_list(fmt) {
|
||||||
if (list_empty(&fmt->list))
|
if (!list_empty(&fmt->list))
|
||||||
perf_hpp__column_register(fmt);
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sort entry fields are dynamically created,
|
||||||
|
* so they can share a same sort key even though
|
||||||
|
* the list is empty.
|
||||||
|
*/
|
||||||
|
if (perf_hpp__is_sort_entry(fmt)) {
|
||||||
|
struct perf_hpp_fmt *pos;
|
||||||
|
|
||||||
|
perf_hpp__for_each_format(pos) {
|
||||||
|
if (perf_hpp__same_sort_entry(pos, fmt))
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perf_hpp__column_register(fmt);
|
||||||
|
next:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void perf_hpp__append_sort_keys(void)
|
||||||
|
{
|
||||||
|
struct perf_hpp_fmt *fmt;
|
||||||
|
|
||||||
|
/* append output fields to sort keys */
|
||||||
|
perf_hpp__for_each_format(fmt) {
|
||||||
|
if (!list_empty(&fmt->sort_list))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sort entry fields are dynamically created,
|
||||||
|
* so they can share a same sort key even though
|
||||||
|
* the list is empty.
|
||||||
|
*/
|
||||||
|
if (perf_hpp__is_sort_entry(fmt)) {
|
||||||
|
struct perf_hpp_fmt *pos;
|
||||||
|
|
||||||
|
perf_hpp__for_each_sort_list(pos) {
|
||||||
|
if (perf_hpp__same_sort_entry(pos, fmt))
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perf_hpp__register_sort_field(fmt);
|
||||||
|
next:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,10 @@ void perf_hpp__column_register(struct perf_hpp_fmt *format);
|
||||||
void perf_hpp__column_enable(unsigned col);
|
void perf_hpp__column_enable(unsigned col);
|
||||||
void perf_hpp__register_sort_field(struct perf_hpp_fmt *format);
|
void perf_hpp__register_sort_field(struct perf_hpp_fmt *format);
|
||||||
void perf_hpp__setup_output_field(void);
|
void perf_hpp__setup_output_field(void);
|
||||||
|
void perf_hpp__append_sort_keys(void);
|
||||||
|
|
||||||
|
bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format);
|
||||||
|
bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b);
|
||||||
|
|
||||||
typedef u64 (*hpp_field_fn)(struct hist_entry *he);
|
typedef u64 (*hpp_field_fn)(struct hist_entry *he);
|
||||||
typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);
|
typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);
|
||||||
|
|
|
@ -13,6 +13,7 @@ const char default_mem_sort_order[] = "local_weight,mem,sym,dso,symbol_daddr,dso
|
||||||
const char default_top_sort_order[] = "dso,symbol";
|
const char default_top_sort_order[] = "dso,symbol";
|
||||||
const char default_diff_sort_order[] = "dso,symbol";
|
const char default_diff_sort_order[] = "dso,symbol";
|
||||||
const char *sort_order;
|
const char *sort_order;
|
||||||
|
const char *field_order;
|
||||||
regex_t ignore_callees_regex;
|
regex_t ignore_callees_regex;
|
||||||
int have_ignore_callees = 0;
|
int have_ignore_callees = 0;
|
||||||
int sort__need_collapse = 0;
|
int sort__need_collapse = 0;
|
||||||
|
@ -1057,6 +1058,20 @@ struct hpp_sort_entry {
|
||||||
struct sort_entry *se;
|
struct sort_entry *se;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
|
||||||
|
{
|
||||||
|
struct hpp_sort_entry *hse_a;
|
||||||
|
struct hpp_sort_entry *hse_b;
|
||||||
|
|
||||||
|
if (!perf_hpp__is_sort_entry(a) || !perf_hpp__is_sort_entry(b))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
hse_a = container_of(a, struct hpp_sort_entry, hpp);
|
||||||
|
hse_b = container_of(b, struct hpp_sort_entry, hpp);
|
||||||
|
|
||||||
|
return hse_a->se == hse_b->se;
|
||||||
|
}
|
||||||
|
|
||||||
static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
|
static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
|
||||||
struct perf_evsel *evsel)
|
struct perf_evsel *evsel)
|
||||||
{
|
{
|
||||||
|
@ -1092,14 +1107,15 @@ static int __sort__hpp_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
|
||||||
return hse->se->se_snprintf(he, hpp->buf, hpp->size, len);
|
return hse->se->se_snprintf(he, hpp->buf, hpp->size, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __sort_dimension__add_hpp(struct sort_dimension *sd)
|
static struct hpp_sort_entry *
|
||||||
|
__sort_dimension__alloc_hpp(struct sort_dimension *sd)
|
||||||
{
|
{
|
||||||
struct hpp_sort_entry *hse;
|
struct hpp_sort_entry *hse;
|
||||||
|
|
||||||
hse = malloc(sizeof(*hse));
|
hse = malloc(sizeof(*hse));
|
||||||
if (hse == NULL) {
|
if (hse == NULL) {
|
||||||
pr_err("Memory allocation failed\n");
|
pr_err("Memory allocation failed\n");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hse->se = sd->entry;
|
hse->se = sd->entry;
|
||||||
|
@ -1115,16 +1131,42 @@ static int __sort_dimension__add_hpp(struct sort_dimension *sd)
|
||||||
INIT_LIST_HEAD(&hse->hpp.list);
|
INIT_LIST_HEAD(&hse->hpp.list);
|
||||||
INIT_LIST_HEAD(&hse->hpp.sort_list);
|
INIT_LIST_HEAD(&hse->hpp.sort_list);
|
||||||
|
|
||||||
|
return hse;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format)
|
||||||
|
{
|
||||||
|
return format->header == __sort__hpp_header;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd)
|
||||||
|
{
|
||||||
|
struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd);
|
||||||
|
|
||||||
|
if (hse == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
perf_hpp__register_sort_field(&hse->hpp);
|
perf_hpp__register_sort_field(&hse->hpp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __sort_dimension__add_hpp_output(struct sort_dimension *sd)
|
||||||
|
{
|
||||||
|
struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd);
|
||||||
|
|
||||||
|
if (hse == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
perf_hpp__column_register(&hse->hpp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
|
static int __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
|
||||||
{
|
{
|
||||||
if (sd->taken)
|
if (sd->taken)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (__sort_dimension__add_hpp(sd) < 0)
|
if (__sort_dimension__add_hpp_sort(sd) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (sd->entry->se_collapse)
|
if (sd->entry->se_collapse)
|
||||||
|
@ -1149,6 +1191,28 @@ static int __hpp_dimension__add(struct hpp_dimension *hd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __sort_dimension__add_output(struct sort_dimension *sd)
|
||||||
|
{
|
||||||
|
if (sd->taken)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (__sort_dimension__add_hpp_output(sd) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sd->taken = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __hpp_dimension__add_output(struct hpp_dimension *hd)
|
||||||
|
{
|
||||||
|
if (!hd->taken) {
|
||||||
|
hd->taken = 1;
|
||||||
|
|
||||||
|
perf_hpp__column_register(hd->fmt);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int sort_dimension__add(const char *tok)
|
int sort_dimension__add(const char *tok)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -1237,14 +1301,23 @@ static const char *get_default_sort_order(void)
|
||||||
return default_sort_orders[sort__mode];
|
return default_sort_orders[sort__mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
int setup_sorting(void)
|
static int __setup_sorting(void)
|
||||||
{
|
{
|
||||||
char *tmp, *tok, *str;
|
char *tmp, *tok, *str;
|
||||||
const char *sort_keys = sort_order;
|
const char *sort_keys = sort_order;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (sort_keys == NULL)
|
if (sort_keys == NULL) {
|
||||||
|
if (field_order) {
|
||||||
|
/*
|
||||||
|
* If user specified field order but no sort order,
|
||||||
|
* we'll honor it and not add default sort orders.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sort_keys = get_default_sort_order();
|
sort_keys = get_default_sort_order();
|
||||||
|
}
|
||||||
|
|
||||||
str = strdup(sort_keys);
|
str = strdup(sort_keys);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
|
@ -1331,3 +1404,129 @@ void sort__setup_elide(FILE *output)
|
||||||
list_for_each_entry(se, &hist_entry__sort_list, list)
|
list_for_each_entry(se, &hist_entry__sort_list, list)
|
||||||
se->elide = false;
|
se->elide = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int output_field_add(char *tok)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) {
|
||||||
|
struct sort_dimension *sd = &common_sort_dimensions[i];
|
||||||
|
|
||||||
|
if (strncasecmp(tok, sd->name, strlen(tok)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return __sort_dimension__add_output(sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) {
|
||||||
|
struct hpp_dimension *hd = &hpp_sort_dimensions[i];
|
||||||
|
|
||||||
|
if (strncasecmp(tok, hd->name, strlen(tok)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return __hpp_dimension__add_output(hd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) {
|
||||||
|
struct sort_dimension *sd = &bstack_sort_dimensions[i];
|
||||||
|
|
||||||
|
if (strncasecmp(tok, sd->name, strlen(tok)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return __sort_dimension__add_output(sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
|
||||||
|
struct sort_dimension *sd = &memory_sort_dimensions[i];
|
||||||
|
|
||||||
|
if (strncasecmp(tok, sd->name, strlen(tok)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return __sort_dimension__add_output(sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_dimensions(void)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++)
|
||||||
|
common_sort_dimensions[i].taken = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++)
|
||||||
|
hpp_sort_dimensions[i].taken = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++)
|
||||||
|
bstack_sort_dimensions[i].taken = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++)
|
||||||
|
memory_sort_dimensions[i].taken = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __setup_output_field(void)
|
||||||
|
{
|
||||||
|
char *tmp, *tok, *str;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (field_order == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
reset_dimensions();
|
||||||
|
|
||||||
|
str = strdup(field_order);
|
||||||
|
if (str == NULL) {
|
||||||
|
error("Not enough memory to setup output fields");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tok = strtok_r(str, ", ", &tmp);
|
||||||
|
tok; tok = strtok_r(NULL, ", ", &tmp)) {
|
||||||
|
ret = output_field_add(tok);
|
||||||
|
if (ret == -EINVAL) {
|
||||||
|
error("Invalid --fields key: `%s'", tok);
|
||||||
|
break;
|
||||||
|
} else if (ret == -ESRCH) {
|
||||||
|
error("Unknown --fields key: `%s'", tok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setup_sorting(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = __setup_sorting();
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (parent_pattern != default_parent_pattern) {
|
||||||
|
err = sort_dimension__add("parent");
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_dimensions();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* perf diff doesn't use default hpp output fields.
|
||||||
|
*/
|
||||||
|
if (sort__mode != SORT_MODE__DIFF)
|
||||||
|
perf_hpp__init();
|
||||||
|
|
||||||
|
err = __setup_output_field();
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* copy sort keys to output fields */
|
||||||
|
perf_hpp__setup_output_field();
|
||||||
|
/* and then copy output fields to sort keys */
|
||||||
|
perf_hpp__append_sort_keys();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
extern regex_t parent_regex;
|
extern regex_t parent_regex;
|
||||||
extern const char *sort_order;
|
extern const char *sort_order;
|
||||||
|
extern const char *field_order;
|
||||||
extern const char default_parent_pattern[];
|
extern const char default_parent_pattern[];
|
||||||
extern const char *parent_pattern;
|
extern const char *parent_pattern;
|
||||||
extern const char default_sort_order[];
|
extern const char default_sort_order[];
|
||||||
|
@ -191,6 +192,7 @@ extern struct sort_entry sort_thread;
|
||||||
extern struct list_head hist_entry__sort_list;
|
extern struct list_head hist_entry__sort_list;
|
||||||
|
|
||||||
int setup_sorting(void);
|
int setup_sorting(void);
|
||||||
|
int setup_output_field(void);
|
||||||
extern int sort_dimension__add(const char *);
|
extern int sort_dimension__add(const char *);
|
||||||
void sort__setup_elide(FILE *fp);
|
void sort__setup_elide(FILE *fp);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue