static int process_sample_event(event_t *event) { struct sample_data data; struct trace_entry *te; memset(&data, 0, sizeof(data)); event__parse_sample(event, sample_type, &data); if (sample_type & PERF_SAMPLE_TIME) { if (!first_time || first_time > data.time) first_time = data.time; if (last_time < data.time) last_time = data.time; } te = (void *)data.raw_data; if (sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { char *event_str; struct power_entry *pe; pe = (void *)te; event_str = perf_header__find_event(te->type); if (!event_str) return 0; if (strcmp(event_str, "power:power_start") == 0) c_state_start(data.cpu, data.time, pe->value); if (strcmp(event_str, "power:power_end") == 0) c_state_end(data.cpu, data.time); if (strcmp(event_str, "power:power_frequency") == 0) p_state_change(data.cpu, data.time, pe->value); if (strcmp(event_str, "sched:sched_wakeup") == 0) sched_wakeup(data.cpu, data.time, data.pid, te); if (strcmp(event_str, "sched:sched_switch") == 0) sched_switch(data.cpu, data.time, te); } return 0; }
static int diff__process_sample_event(event_t *event, struct perf_session *session) { struct addr_location al; struct sample_data data = { .period = 1, }; dump_printf("(IP, %d): %d: %p\n", event->header.misc, event->ip.pid, (void *)(long)event->ip.ip); if (event__preprocess_sample(event, session, &al, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; } if (al.filtered) return 0; event__parse_sample(event, session->sample_type, &data); if (al.sym && perf_session__add_hist_entry(session, &al, data.period)) { pr_warning("problem incrementing symbol count, skipping event\n"); return -1; } session->events_stats.total += data.period; return 0; } static struct perf_event_ops event_ops = { .process_sample_event = diff__process_sample_event, .process_mmap_event = event__process_mmap, .process_comm_event = event__process_comm, .process_exit_event = event__process_task, .process_fork_event = event__process_task, .process_lost_event = event__process_lost, }; static void perf_session__insert_hist_entry_by_name(struct rb_root *root, struct hist_entry *he) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct hist_entry *iter; while (*p != NULL) { int cmp; parent = *p; iter = rb_entry(parent, struct hist_entry, rb_node); cmp = strcmp(he->map->dso->name, iter->map->dso->name); if (cmp > 0) p = &(*p)->rb_left; else if (cmp < 0) p = &(*p)->rb_right; else { cmp = strcmp(he->sym->name, iter->sym->name); if (cmp > 0) p = &(*p)->rb_left; else p = &(*p)->rb_right; } } rb_link_node(&he->rb_node, parent, p); rb_insert_color(&he->rb_node, root); } static void perf_session__resort_by_name(struct perf_session *self) { unsigned long position = 1; struct rb_root tmp = RB_ROOT; struct rb_node *next = rb_first(&self->hists); while (next != NULL) { struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); rb_erase(&n->rb_node, &self->hists); n->position = position++; perf_session__insert_hist_entry_by_name(&tmp, n); } self->hists = tmp; }
static int diff__process_sample_event(event_t *event, struct perf_session *session) { struct addr_location al; struct sample_data data = { .period = 1, }; dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc, event->ip.pid, event->ip.ip); if (event__preprocess_sample(event, session, &al, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; } if (al.filtered || al.sym == NULL) return 0; event__parse_sample(event, session->sample_type, &data); if (hists__add_entry(&session->hists, &al, data.period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } session->hists.stats.total_period += data.period; return 0; } static struct perf_event_ops event_ops = { .sample = diff__process_sample_event, .mmap = event__process_mmap, .comm = event__process_comm, .exit = event__process_task, .fork = event__process_task, .lost = event__process_lost, }; static void perf_session__insert_hist_entry_by_name(struct rb_root *root, struct hist_entry *he) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct hist_entry *iter; while (*p != NULL) { parent = *p; iter = rb_entry(parent, struct hist_entry, rb_node); if (hist_entry__cmp(he, iter) < 0) p = &(*p)->rb_left; else p = &(*p)->rb_right; } rb_link_node(&he->rb_node, parent, p); rb_insert_color(&he->rb_node, root); } static void hists__resort_entries(struct hists *self) { unsigned long position = 1; struct rb_root tmp = RB_ROOT; struct rb_node *next = rb_first(&self->entries); while (next != NULL) { struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); rb_erase(&n->rb_node, &self->entries); n->position = position++; perf_session__insert_hist_entry_by_name(&tmp, n); } self->entries = tmp; }