#include "util.h"
#include "build-id.h"
#include "hist.h"
#include "session.h"
#include "sort.h"
#include <math.h>
enum hist_filter {
HIST_FILTER__DSO,
HIST_FILTER__THREAD,
HIST_FILTER__PARENT,
};
struct callchain_param callchain_param = {
.mode = CHAIN_GRAPH_REL,
.min_percent = 0.5
};
u16 hists__col_len(struct hists *self, enum hist_column col)
{
return self->col_len[col];
}
void hists__set_col_len(struct hists *self, enum hist_column col, u16 len)
{
self->col_len[col] = len;
}
bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len)
{
if (len > hists__col_len(self, col)) {
hists__set_col_len(self, col, len);
return true;
}
return false;
}
static void hists__reset_col_len(struct hists *self)
{
enum hist_column col;
for (col = 0; col < HISTC_NR_COLS; ++col)
hists__set_col_len(self, col, 0);
}
static void hists__calc_col_len(struct hists *self, struct hist_entry *h)
{
u16 len;
if (h->ms.sym)
hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen);
len = thread__comm_len(h->thread);
if (hists__new_col_len(self, HISTC_COMM, len))
hists__set_col_len(self, HISTC_THREAD, len + 6);
if (h->ms.map) {
len = dso__name_len(h->ms.map->dso);
hists__new_col_len(self, HISTC_DSO, len);
}
}
static void hist_entry__add_cpumode_period(struct hist_entry *self,
unsigned int cpumode, u64 period)
{
switch (cpumode) {
case PERF_RECORD_MISC_KERNEL:
self->period_sys += period;
break;
case PERF_RECORD_MISC_USER:
self->period_us += period;
break;
case PERF_RECORD_MISC_GUEST_KERNEL:
self->period_guest_sys += period;
break;
case PERF_RECORD_MISC_GUEST_USER:
self->period_guest_us += period;
break;
default:
break;
}
}
/*
* histogram, sorted on item, collects periods
*/
static struct hist_entry *hist_entry__new(struct hist_entry *template)
{
size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0;
struct hist_entry *self = malloc(sizeof(*self) + callchain_size);
if (self != NULL) {
*self = *template;
self->nr_events = 1;
if (self->ms.map)
self->ms.map->