af0a6fa463
While recursively printing the branches of each callchains, we forget to display the root. It is never printed. Say we have: symbol f1 f2 | -------- f3 | f4 | ---------f5 f6 Actually we never see that, instead it displays: symbol | --------- f3 | f4 | --------- f5 f6 However f1 is always the same than "symbol" and if we are sorting by symbols first then "symbol", f1 and f2 will be well aligned like in the above example, so displaying f1 looks redundant here. But if we are sorting by something else first (dso, comm, etc...), displaying f1 doesn't look redundant but rather necessary because the symbol is not well aligned anymore with its callchain: comm dso symbol f1 f2 | --------- [...] And we want the callchain to be obvious. So we fix the bug by printing the root branch, but we also filter its first entry if we are sorting by symbols first. Reported-by: Anton Blanchard <anton@samba.org> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1256246604-17156-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
91 lines
2.6 KiB
C
91 lines
2.6 KiB
C
#ifndef __PERF_SORT_H
|
|
#define __PERF_SORT_H
|
|
#include "../builtin.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "color.h"
|
|
#include <linux/list.h>
|
|
#include "cache.h"
|
|
#include <linux/rbtree.h>
|
|
#include "symbol.h"
|
|
#include "string.h"
|
|
#include "callchain.h"
|
|
#include "strlist.h"
|
|
#include "values.h"
|
|
|
|
#include "../perf.h"
|
|
#include "debug.h"
|
|
#include "header.h"
|
|
|
|
#include "parse-options.h"
|
|
#include "parse-events.h"
|
|
|
|
#include "thread.h"
|
|
#include "sort.h"
|
|
|
|
extern regex_t parent_regex;
|
|
extern char *sort_order;
|
|
extern char default_parent_pattern[];
|
|
extern char *parent_pattern;
|
|
extern char default_sort_order[];
|
|
extern int sort__need_collapse;
|
|
extern int sort__has_parent;
|
|
extern char *field_sep;
|
|
extern struct sort_entry sort_comm;
|
|
extern struct sort_entry sort_dso;
|
|
extern struct sort_entry sort_sym;
|
|
extern struct sort_entry sort_parent;
|
|
extern unsigned int dsos__col_width;
|
|
extern unsigned int comms__col_width;
|
|
extern unsigned int threads__col_width;
|
|
extern int sort_by_sym_first;
|
|
|
|
struct hist_entry {
|
|
struct rb_node rb_node;
|
|
u64 count;
|
|
struct thread *thread;
|
|
struct map *map;
|
|
struct symbol *sym;
|
|
u64 ip;
|
|
char level;
|
|
struct symbol *parent;
|
|
struct callchain_node callchain;
|
|
struct rb_root sorted_chain;
|
|
};
|
|
|
|
/*
|
|
* configurable sorting bits
|
|
*/
|
|
|
|
struct sort_entry {
|
|
struct list_head list;
|
|
|
|
const char *header;
|
|
|
|
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);
|
|
unsigned int *width;
|
|
bool elide;
|
|
};
|
|
|
|
extern struct sort_entry sort_thread;
|
|
extern struct list_head hist_entry__sort_list;
|
|
|
|
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);
|
|
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 *);
|
|
extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int);
|
|
extern int sort_dimension__add(const char *);
|
|
|
|
#endif /* __PERF_SORT_H */
|