perf session: Move the hist_entries rb tree to perf_session
As we'll need to sort multiple times for multiple perf sessions, so that we can then do a diff. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1260803439-16783-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
b9bf089212
commit
4e4f06e4c8
|
@ -121,10 +121,12 @@ static void hist_hit(struct hist_entry *he, u64 ip)
|
||||||
h->ip[offset]);
|
h->ip[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hist_entry__add(struct addr_location *al, u64 count)
|
static int perf_session__add_hist_entry(struct perf_session *self,
|
||||||
|
struct addr_location *al, u64 count)
|
||||||
{
|
{
|
||||||
bool hit;
|
bool hit;
|
||||||
struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit);
|
struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL,
|
||||||
|
count, &hit);
|
||||||
if (he == NULL)
|
if (he == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
hist_hit(he, al->addr);
|
hist_hit(he, al->addr);
|
||||||
|
@ -144,7 +146,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hist_entry__add(&al, 1)) {
|
if (perf_session__add_hist_entry(session, &al, 1)) {
|
||||||
fprintf(stderr, "problem incrementing symbol count, "
|
fprintf(stderr, "problem incrementing symbol count, "
|
||||||
"skipping event\n");
|
"skipping event\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -428,11 +430,11 @@ static void annotate_sym(struct hist_entry *he)
|
||||||
free_source_line(he, len);
|
free_source_line(he, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_annotations(void)
|
static void perf_session__find_annotations(struct perf_session *self)
|
||||||
{
|
{
|
||||||
struct rb_node *nd;
|
struct rb_node *nd;
|
||||||
|
|
||||||
for (nd = rb_first(&hist); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
|
||||||
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
|
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
struct sym_priv *priv;
|
struct sym_priv *priv;
|
||||||
|
|
||||||
|
@ -484,10 +486,9 @@ static int __cmd_annotate(void)
|
||||||
if (verbose > 2)
|
if (verbose > 2)
|
||||||
dsos__fprintf(stdout);
|
dsos__fprintf(stdout);
|
||||||
|
|
||||||
collapse__resort();
|
perf_session__collapse_resort(session);
|
||||||
output__resort(event__total[0]);
|
perf_session__output_resort(session, event__total[0]);
|
||||||
|
perf_session__find_annotations(session);
|
||||||
find_annotations();
|
|
||||||
out_delete:
|
out_delete:
|
||||||
perf_session__delete(session);
|
perf_session__delete(session);
|
||||||
|
|
||||||
|
|
|
@ -344,7 +344,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_type_check(u64 type)
|
static int sample_type_check(u64 type, struct perf_session *session __used)
|
||||||
{
|
{
|
||||||
sample_type = type;
|
sample_type = type;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ static char *dso_list_str, *comm_list_str, *sym_list_str,
|
||||||
static struct strlist *dso_list, *comm_list, *sym_list;
|
static struct strlist *dso_list, *comm_list, *sym_list;
|
||||||
|
|
||||||
static int force;
|
static int force;
|
||||||
|
static bool use_callchain;
|
||||||
|
|
||||||
static int show_nr_samples;
|
static int show_nr_samples;
|
||||||
|
|
||||||
|
@ -312,8 +313,9 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
|
||||||
hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
|
struct perf_session *session,
|
||||||
|
u64 total_samples)
|
||||||
{
|
{
|
||||||
struct sort_entry *se;
|
struct sort_entry *se;
|
||||||
size_t ret;
|
size_t ret;
|
||||||
|
@ -345,7 +347,7 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
|
||||||
|
|
||||||
ret += fprintf(fp, "\n");
|
ret += fprintf(fp, "\n");
|
||||||
|
|
||||||
if (callchain) {
|
if (session->use_callchain) {
|
||||||
int left_margin = 0;
|
int left_margin = 0;
|
||||||
|
|
||||||
if (sort__first_dimension == SORT_COMM) {
|
if (sort__first_dimension == SORT_COMM) {
|
||||||
|
@ -422,7 +424,7 @@ static struct symbol **resolve_callchain(struct thread *thread,
|
||||||
struct symbol **syms = NULL;
|
struct symbol **syms = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (callchain) {
|
if (session->use_callchain) {
|
||||||
syms = calloc(chain->nr, sizeof(*syms));
|
syms = calloc(chain->nr, sizeof(*syms));
|
||||||
if (!syms) {
|
if (!syms) {
|
||||||
fprintf(stderr, "Can't allocate memory for symbols\n");
|
fprintf(stderr, "Can't allocate memory for symbols\n");
|
||||||
|
@ -454,7 +456,7 @@ static struct symbol **resolve_callchain(struct thread *thread,
|
||||||
if (sort__has_parent && !*parent &&
|
if (sort__has_parent && !*parent &&
|
||||||
call__match(al.sym))
|
call__match(al.sym))
|
||||||
*parent = al.sym;
|
*parent = al.sym;
|
||||||
if (!callchain)
|
if (!session->use_callchain)
|
||||||
break;
|
break;
|
||||||
syms[i] = al.sym;
|
syms[i] = al.sym;
|
||||||
}
|
}
|
||||||
|
@ -467,25 +469,25 @@ static struct symbol **resolve_callchain(struct thread *thread,
|
||||||
* collect histogram counts
|
* collect histogram counts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int hist_entry__add(struct addr_location *al,
|
static int perf_session__add_hist_entry(struct perf_session *self,
|
||||||
struct perf_session *session,
|
struct addr_location *al,
|
||||||
struct ip_callchain *chain, u64 count)
|
struct ip_callchain *chain, u64 count)
|
||||||
{
|
{
|
||||||
struct symbol **syms = NULL, *parent = NULL;
|
struct symbol **syms = NULL, *parent = NULL;
|
||||||
bool hit;
|
bool hit;
|
||||||
struct hist_entry *he;
|
struct hist_entry *he;
|
||||||
|
|
||||||
if ((sort__has_parent || callchain) && chain)
|
if ((sort__has_parent || self->use_callchain) && chain)
|
||||||
syms = resolve_callchain(al->thread, session, chain, &parent);
|
syms = resolve_callchain(al->thread, self, chain, &parent);
|
||||||
|
|
||||||
he = __hist_entry__add(al, parent, count, &hit);
|
he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
|
||||||
if (he == NULL)
|
if (he == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (hit)
|
if (hit)
|
||||||
he->count += count;
|
he->count += count;
|
||||||
|
|
||||||
if (callchain) {
|
if (self->use_callchain) {
|
||||||
if (!hit)
|
if (!hit)
|
||||||
callchain_init(&he->callchain);
|
callchain_init(&he->callchain);
|
||||||
append_chain(&he->callchain, chain, syms);
|
append_chain(&he->callchain, chain, syms);
|
||||||
|
@ -495,7 +497,8 @@ static int hist_entry__add(struct addr_location *al,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t output__fprintf(FILE *fp, u64 total_samples)
|
static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
|
||||||
|
u64 total_samples, FILE *fp)
|
||||||
{
|
{
|
||||||
struct hist_entry *pos;
|
struct hist_entry *pos;
|
||||||
struct sort_entry *se;
|
struct sort_entry *se;
|
||||||
|
@ -567,9 +570,9 @@ static size_t output__fprintf(FILE *fp, u64 total_samples)
|
||||||
fprintf(fp, "#\n");
|
fprintf(fp, "#\n");
|
||||||
|
|
||||||
print_entries:
|
print_entries:
|
||||||
for (nd = rb_first(&hist); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
|
||||||
pos = rb_entry(nd, struct hist_entry, rb_node);
|
pos = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
ret += hist_entry__fprintf(fp, pos, total_samples);
|
ret += hist_entry__fprintf(fp, pos, self, total_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sort_order == default_sort_order &&
|
if (sort_order == default_sort_order &&
|
||||||
|
@ -671,7 +674,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
|
||||||
if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
|
if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (hist_entry__add(&al, session, data.callchain, data.period)) {
|
if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
|
||||||
pr_debug("problem incrementing symbol count, skipping event\n");
|
pr_debug("problem incrementing symbol count, skipping event\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -719,7 +722,7 @@ static int process_read_event(event_t *event, struct perf_session *session __use
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_type_check(u64 type)
|
static int sample_type_check(u64 type, struct perf_session *session)
|
||||||
{
|
{
|
||||||
sample_type = type;
|
sample_type = type;
|
||||||
|
|
||||||
|
@ -730,14 +733,14 @@ static int sample_type_check(u64 type)
|
||||||
" perf record without -g?\n");
|
" perf record without -g?\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (callchain) {
|
if (session->use_callchain) {
|
||||||
fprintf(stderr, "selected -g but no callchain data."
|
fprintf(stderr, "selected -g but no callchain data."
|
||||||
" Did you call perf record without"
|
" Did you call perf record without"
|
||||||
" -g?\n");
|
" -g?\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (callchain_param.mode != CHAIN_NONE && !callchain) {
|
} else if (callchain_param.mode != CHAIN_NONE && !session->use_callchain) {
|
||||||
callchain = 1;
|
session->use_callchain = true;
|
||||||
if (register_callchain_param(&callchain_param) < 0) {
|
if (register_callchain_param(&callchain_param) < 0) {
|
||||||
fprintf(stderr, "Can't register callchain"
|
fprintf(stderr, "Can't register callchain"
|
||||||
" params\n");
|
" params\n");
|
||||||
|
@ -769,6 +772,8 @@ static int __cmd_report(void)
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
session->use_callchain = use_callchain;
|
||||||
|
|
||||||
if (show_threads)
|
if (show_threads)
|
||||||
perf_read_values_init(&show_threads_values);
|
perf_read_values_init(&show_threads_values);
|
||||||
|
|
||||||
|
@ -787,9 +792,9 @@ static int __cmd_report(void)
|
||||||
if (verbose > 2)
|
if (verbose > 2)
|
||||||
dsos__fprintf(stdout);
|
dsos__fprintf(stdout);
|
||||||
|
|
||||||
collapse__resort();
|
perf_session__collapse_resort(session);
|
||||||
output__resort(event__stats.total);
|
perf_session__output_resort(session, event__stats.total);
|
||||||
output__fprintf(stdout, event__stats.total);
|
perf_session__fprintf_hist_entries(session, event__stats.total, stdout);
|
||||||
|
|
||||||
if (show_threads)
|
if (show_threads)
|
||||||
perf_read_values_destroy(&show_threads_values);
|
perf_read_values_destroy(&show_threads_values);
|
||||||
|
@ -805,7 +810,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
|
||||||
char *tok;
|
char *tok;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
callchain = 1;
|
use_callchain = true;
|
||||||
|
|
||||||
if (!arg)
|
if (!arg)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -826,7 +831,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
|
||||||
|
|
||||||
else if (!strncmp(tok, "none", strlen(arg))) {
|
else if (!strncmp(tok, "none", strlen(arg))) {
|
||||||
callchain_param.mode = CHAIN_NONE;
|
callchain_param.mode = CHAIN_NONE;
|
||||||
callchain = 0;
|
use_callchain = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1655,7 +1655,7 @@ static int process_lost_event(event_t *event __used,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_type_check(u64 type)
|
static int sample_type_check(u64 type, struct perf_session *session __used)
|
||||||
{
|
{
|
||||||
sample_type = type;
|
sample_type = type;
|
||||||
|
|
||||||
|
|
|
@ -1033,7 +1033,7 @@ static void process_samples(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_type_check(u64 type)
|
static int sample_type_check(u64 type, struct perf_session *session __used)
|
||||||
{
|
{
|
||||||
sample_type = type;
|
sample_type = type;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_type_check(u64 type)
|
static int sample_type_check(u64 type, struct perf_session *session __used)
|
||||||
{
|
{
|
||||||
sample_type = type;
|
sample_type = type;
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ int perf_session__process_events(struct perf_session *self,
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (ops->sample_type_check &&
|
if (ops->sample_type_check &&
|
||||||
ops->sample_type_check(sample_type) < 0)
|
ops->sample_type_check(sample_type, self) < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
if (!ops->full_paths) {
|
if (!ops->full_paths) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "hist.h"
|
#include "hist.h"
|
||||||
|
#include "session.h"
|
||||||
struct rb_root hist;
|
#include "sort.h"
|
||||||
int callchain;
|
|
||||||
|
|
||||||
struct callchain_param callchain_param = {
|
struct callchain_param callchain_param = {
|
||||||
.mode = CHAIN_GRAPH_REL,
|
.mode = CHAIN_GRAPH_REL,
|
||||||
|
@ -12,11 +11,12 @@ struct callchain_param callchain_param = {
|
||||||
* histogram, sorted on item, collects counts
|
* histogram, sorted on item, collects counts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct hist_entry *__hist_entry__add(struct addr_location *al,
|
struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
|
||||||
struct symbol *sym_parent,
|
struct addr_location *al,
|
||||||
u64 count, bool *hit)
|
struct symbol *sym_parent,
|
||||||
|
u64 count, bool *hit)
|
||||||
{
|
{
|
||||||
struct rb_node **p = &hist.rb_node;
|
struct rb_node **p = &self->hists.rb_node;
|
||||||
struct rb_node *parent = NULL;
|
struct rb_node *parent = NULL;
|
||||||
struct hist_entry *he;
|
struct hist_entry *he;
|
||||||
struct hist_entry entry = {
|
struct hist_entry entry = {
|
||||||
|
@ -52,7 +52,7 @@ struct hist_entry *__hist_entry__add(struct addr_location *al,
|
||||||
return NULL;
|
return NULL;
|
||||||
*he = entry;
|
*he = entry;
|
||||||
rb_link_node(&he->rb_node, parent, p);
|
rb_link_node(&he->rb_node, parent, p);
|
||||||
rb_insert_color(&he->rb_node, &hist);
|
rb_insert_color(&he->rb_node, &self->hists);
|
||||||
*hit = false;
|
*hit = false;
|
||||||
return he;
|
return he;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
|
||||||
rb_insert_color(&he->rb_node, root);
|
rb_insert_color(&he->rb_node, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
void collapse__resort(void)
|
void perf_session__collapse_resort(struct perf_session *self)
|
||||||
{
|
{
|
||||||
struct rb_root tmp;
|
struct rb_root tmp;
|
||||||
struct rb_node *next;
|
struct rb_node *next;
|
||||||
|
@ -139,31 +139,33 @@ void collapse__resort(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp = RB_ROOT;
|
tmp = RB_ROOT;
|
||||||
next = rb_first(&hist);
|
next = rb_first(&self->hists);
|
||||||
|
|
||||||
while (next) {
|
while (next) {
|
||||||
n = rb_entry(next, struct hist_entry, rb_node);
|
n = rb_entry(next, struct hist_entry, rb_node);
|
||||||
next = rb_next(&n->rb_node);
|
next = rb_next(&n->rb_node);
|
||||||
|
|
||||||
rb_erase(&n->rb_node, &hist);
|
rb_erase(&n->rb_node, &self->hists);
|
||||||
collapse__insert_entry(&tmp, n);
|
collapse__insert_entry(&tmp, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
hist = tmp;
|
self->hists = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reverse the map, sort on count.
|
* reverse the map, sort on count.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void output__insert_entry(struct rb_root *root, struct hist_entry *he,
|
static void perf_session__insert_output_hist_entry(struct perf_session *self,
|
||||||
u64 min_callchain_hits)
|
struct rb_root *root,
|
||||||
|
struct hist_entry *he,
|
||||||
|
u64 min_callchain_hits)
|
||||||
{
|
{
|
||||||
struct rb_node **p = &root->rb_node;
|
struct rb_node **p = &root->rb_node;
|
||||||
struct rb_node *parent = NULL;
|
struct rb_node *parent = NULL;
|
||||||
struct hist_entry *iter;
|
struct hist_entry *iter;
|
||||||
|
|
||||||
if (callchain)
|
if (self->use_callchain)
|
||||||
callchain_param.sort(&he->sorted_chain, &he->callchain,
|
callchain_param.sort(&he->sorted_chain, &he->callchain,
|
||||||
min_callchain_hits, &callchain_param);
|
min_callchain_hits, &callchain_param);
|
||||||
|
|
||||||
|
@ -181,7 +183,7 @@ static void output__insert_entry(struct rb_root *root, struct hist_entry *he,
|
||||||
rb_insert_color(&he->rb_node, root);
|
rb_insert_color(&he->rb_node, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
void output__resort(u64 total_samples)
|
void perf_session__output_resort(struct perf_session *self, u64 total_samples)
|
||||||
{
|
{
|
||||||
struct rb_root tmp;
|
struct rb_root tmp;
|
||||||
struct rb_node *next;
|
struct rb_node *next;
|
||||||
|
@ -192,15 +194,16 @@ void output__resort(u64 total_samples)
|
||||||
total_samples * (callchain_param.min_percent / 100);
|
total_samples * (callchain_param.min_percent / 100);
|
||||||
|
|
||||||
tmp = RB_ROOT;
|
tmp = RB_ROOT;
|
||||||
next = rb_first(&hist);
|
next = rb_first(&self->hists);
|
||||||
|
|
||||||
while (next) {
|
while (next) {
|
||||||
n = rb_entry(next, struct hist_entry, rb_node);
|
n = rb_entry(next, struct hist_entry, rb_node);
|
||||||
next = rb_next(&n->rb_node);
|
next = rb_next(&n->rb_node);
|
||||||
|
|
||||||
rb_erase(&n->rb_node, &hist);
|
rb_erase(&n->rb_node, &self->hists);
|
||||||
output__insert_entry(&tmp, n, min_callchain_hits);
|
perf_session__insert_output_hist_entry(self, &tmp, n,
|
||||||
|
min_callchain_hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
hist = tmp;
|
self->hists = tmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,25 @@
|
||||||
#ifndef __PERF_HIST_H
|
#ifndef __PERF_HIST_H
|
||||||
#define __PERF_HIST_H
|
#define __PERF_HIST_H
|
||||||
#include "../builtin.h"
|
|
||||||
|
|
||||||
#include "util.h"
|
#include <linux/types.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 "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 struct rb_root hist;
|
|
||||||
extern int callchain;
|
|
||||||
extern struct callchain_param callchain_param;
|
extern struct callchain_param callchain_param;
|
||||||
|
|
||||||
struct hist_entry *__hist_entry__add(struct addr_location *al,
|
struct perf_session;
|
||||||
struct symbol *parent,
|
struct hist_entry;
|
||||||
u64 count, bool *hit);
|
struct addr_location;
|
||||||
|
struct symbol;
|
||||||
|
|
||||||
|
struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
|
||||||
|
struct addr_location *al,
|
||||||
|
struct symbol *parent,
|
||||||
|
u64 count, bool *hit);
|
||||||
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
|
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
|
||||||
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
|
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
|
||||||
extern void hist_entry__free(struct hist_entry *);
|
void hist_entry__free(struct hist_entry *);
|
||||||
extern void collapse__resort(void);
|
|
||||||
extern void output__resort(u64);
|
void perf_session__output_resort(struct perf_session *self, u64 total_samples);
|
||||||
|
void perf_session__collapse_resort(struct perf_session *self);
|
||||||
|
|
||||||
#endif /* __PERF_HIST_H */
|
#endif /* __PERF_HIST_H */
|
||||||
|
|
|
@ -16,10 +16,12 @@ struct perf_session {
|
||||||
struct map_groups kmaps;
|
struct map_groups kmaps;
|
||||||
struct rb_root threads;
|
struct rb_root threads;
|
||||||
struct thread *last_match;
|
struct thread *last_match;
|
||||||
|
struct rb_root hists;
|
||||||
int fd;
|
int fd;
|
||||||
int cwdlen;
|
int cwdlen;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
bool use_modules;
|
bool use_modules;
|
||||||
|
bool use_callchain;
|
||||||
char filename[0];
|
char filename[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +37,8 @@ struct perf_event_ops {
|
||||||
event_op process_read_event;
|
event_op process_read_event;
|
||||||
event_op process_throttle_event;
|
event_op process_throttle_event;
|
||||||
event_op process_unthrottle_event;
|
event_op process_unthrottle_event;
|
||||||
int (*sample_type_check)(u64 sample_type);
|
int (*sample_type_check)(u64 sample_type,
|
||||||
|
struct perf_session *session);
|
||||||
unsigned long total_unknown;
|
unsigned long total_unknown;
|
||||||
bool full_paths;
|
bool full_paths;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue