Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169562
b: refs/heads/master
c: 5b2bb75
h: refs/heads/master
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Oct 27, 2009
1 parent 3472f1f commit 76f3fd6
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 234fbbf508c58c5084292b11b242377553897459
refs/heads/master: 5b2bb75a0d4b08cd16bc35ecd674f957fc3b0eb7
143 changes: 101 additions & 42 deletions trunk/tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ static void show_details(struct sym_entry *syme)
}

/*
* Symbols will be added here in record_ip and will get out
* Symbols will be added here in event__process_sample and will get out
* after decayed.
*/
static LIST_HEAD(active_symbols);
Expand Down Expand Up @@ -459,18 +459,18 @@ static void print_sym_table(void)
}

if (nr_counters == 1)
printf(" samples pcnt");
printf(" samples pcnt");
else
printf(" weight samples pcnt");
printf(" weight samples pcnt");

if (verbose)
printf(" RIP ");
printf(" kernel function\n");
printf(" %s _______ _____",
printf(" function DSO\n");
printf(" %s _______ _____",
nr_counters == 1 ? " " : "______");
if (verbose)
printf(" ________________");
printf(" _______________\n\n");
printf(" ________________");
printf(" ________________________________ ________________\n\n");

for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
struct symbol *sym;
Expand All @@ -486,16 +486,15 @@ static void print_sym_table(void)
sum_ksamples));

if (nr_counters == 1 || !display_weighted)
printf("%20.2f - ", syme->weight);
printf("%20.2f ", syme->weight);
else
printf("%9.1f %10ld - ", syme->weight, syme->snap_count);
printf("%9.1f %10ld ", syme->weight, syme->snap_count);

percent_color_fprintf(stdout, "%4.1f%%", pcnt);
if (verbose)
printf(" - %016llx", sym->start);
printf(" : %s", sym->name);
if (syme->map->dso->name[0] == '[')
printf(" \t%s", syme->map->dso->name);
printf(" %016llx", sym->start);
printf(" %-32s", sym->name);
printf(" %s", syme->map->dso->short_name);
printf("\n");
}
}
Expand Down Expand Up @@ -818,41 +817,97 @@ static int parse_symbols(void)
return 0;
}

/*
* Binary search in the histogram table and record the hit:
*/
static void record_ip(u64 ip, int counter)
static void event__process_sample(const event_t *self, int counter)
{
u64 ip = self->ip.ip;
struct map *map;
struct symbol *sym = kernel_maps__find_symbol(ip, &map);

if (sym != NULL) {
struct sym_entry *syme = dso__sym_priv(map->dso, sym);

if (!syme->skip) {
syme->count[counter]++;
record_precise_ip(syme, counter, ip);
pthread_mutex_lock(&active_symbols_lock);
if (list_empty(&syme->node) || !syme->node.next)
__list_insert_active_sym(syme);
pthread_mutex_unlock(&active_symbols_lock);
struct sym_entry *syme;
struct symbol *sym;

switch (self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK) {
case PERF_RECORD_MISC_USER: {
struct thread *thread = threads__findnew(self->ip.pid);

if (thread == NULL)
return;

map = thread__find_map(thread, ip);
if (map != NULL) {
ip = map->map_ip(map, ip);
sym = map->dso->find_symbol(map->dso, ip);
if (sym == NULL)
return;
userspace_samples++;
break;
}
}
/*
* If this is outside of all known maps,
* and is a negative address, try to look it
* up in the kernel dso, as it might be a
* vsyscall or vdso (which executes in user-mode).
*/
if ((long long)ip >= 0)
return;
/* Fall thru */
case PERF_RECORD_MISC_KERNEL:
sym = kernel_maps__find_symbol(ip, &map);
if (sym == NULL)
return;
break;
default:
return;
}

syme = dso__sym_priv(map->dso, sym);

samples--;
if (!syme->skip) {
syme->count[counter]++;
record_precise_ip(syme, counter, ip);
pthread_mutex_lock(&active_symbols_lock);
if (list_empty(&syme->node) || !syme->node.next)
__list_insert_active_sym(syme);
pthread_mutex_unlock(&active_symbols_lock);
++samples;
return;
}
}

static void process_event(u64 ip, int counter, int user)
static void event__process_mmap(event_t *self)
{
samples++;
struct thread *thread = threads__findnew(self->mmap.pid);

if (thread != NULL) {
struct map *map = map__new(&self->mmap, NULL, 0,
sizeof(struct sym_entry),
symbol_filter);
if (map != NULL)
thread__insert_map(thread, map);
}
}

if (user) {
userspace_samples++;
return;
static void event__process_comm(event_t *self)
{
struct thread *thread = threads__findnew(self->comm.pid);

if (thread != NULL)
thread__set_comm(thread, self->comm.comm);
}

static int event__process(event_t *event)
{
switch (event->header.type) {
case PERF_RECORD_COMM:
event__process_comm(event);
break;
case PERF_RECORD_MMAP:
event__process_mmap(event);
break;
default:
break;
}

record_ip(ip, counter);
return 0;
}

struct mmap_data {
Expand Down Expand Up @@ -925,13 +980,11 @@ static void mmap_read_counter(struct mmap_data *md)
event = &event_copy;
}

if (event->header.type == PERF_RECORD_SAMPLE)
event__process_sample(event, md->counter);
else
event__process(event);
old += size;

if (event->header.type == PERF_RECORD_SAMPLE) {
int user =
(event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK) == PERF_RECORD_MISC_USER;
process_event(event->ip.ip, md->counter, user);
}
}

md->prev = old;
Expand Down Expand Up @@ -973,6 +1026,7 @@ static void start_counter(int i, int counter)
}

attr->inherit = (cpu < 0) && inherit;
attr->mmap = 1;

try_again:
fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
Expand Down Expand Up @@ -1031,6 +1085,11 @@ static int __cmd_top(void)
int i, counter;
int ret;

if (target_pid != -1)
event__synthesize_thread(target_pid, event__process);
else
event__synthesize_threads(event__process);

for (i = 0; i < nr_cpus; i++) {
group_fd = -1;
for (counter = 0; counter < nr_counters; counter++)
Expand Down

0 comments on commit 76f3fd6

Please sign in to comment.