diff options
author | Jaroslav Kysela <perex@perex.cz> | 2010-01-08 09:26:34 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2010-01-08 09:26:34 +0100 |
commit | 1cb4f624ea38361b6397966470f0a1bed5532483 (patch) | |
tree | 418b05ddc854b09d64f7d5ee0c78875e42b5f151 /tools/perf/util/data_map.c | |
parent | 444c1953d496d272208902ff7010dc70d1f887f0 (diff) | |
parent | 2c1f1895ef2aa8f0e5497893eff71304aef332e1 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into fixes
Diffstat (limited to 'tools/perf/util/data_map.c')
-rw-r--r-- | tools/perf/util/data_map.c | 163 |
1 files changed, 62 insertions, 101 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 59b65d0bd7c..b557b836de3 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -1,20 +1,17 @@ -#include "data_map.h" #include "symbol.h" #include "util.h" #include "debug.h" +#include "thread.h" +#include "session.h" - -static struct perf_file_handler *curr_handler; -static unsigned long mmap_window = 32; -static char __cwd[PATH_MAX]; - -static int process_event_stub(event_t *event __used) +static int process_event_stub(event_t *event __used, + struct perf_session *session __used) { dump_printf(": unhandled!\n"); return 0; } -void register_perf_file_handler(struct perf_file_handler *handler) +static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) { if (!handler->process_sample_event) handler->process_sample_event = process_event_stub; @@ -34,8 +31,6 @@ void register_perf_file_handler(struct perf_file_handler *handler) handler->process_throttle_event = process_event_stub; if (!handler->process_unthrottle_event) handler->process_unthrottle_event = process_event_stub; - - curr_handler = handler; } static const char *event__name[] = { @@ -61,8 +56,9 @@ void event__print_totals(void) event__name[i], event__total[i]); } -static int -process_event(event_t *event, unsigned long offset, unsigned long head) +static int process_event(event_t *event, struct perf_session *session, + struct perf_event_ops *ops, + unsigned long offset, unsigned long head) { trace_event(event); @@ -77,25 +73,25 @@ process_event(event_t *event, unsigned long offset, unsigned long head) switch (event->header.type) { case PERF_RECORD_SAMPLE: - return curr_handler->process_sample_event(event); + return ops->process_sample_event(event, session); case PERF_RECORD_MMAP: - return curr_handler->process_mmap_event(event); + return ops->process_mmap_event(event, session); case PERF_RECORD_COMM: - return curr_handler->process_comm_event(event); + return ops->process_comm_event(event, session); case PERF_RECORD_FORK: - return curr_handler->process_fork_event(event); + return ops->process_fork_event(event, session); case PERF_RECORD_EXIT: - return curr_handler->process_exit_event(event); + return ops->process_exit_event(event, session); case PERF_RECORD_LOST: - return curr_handler->process_lost_event(event); + return ops->process_lost_event(event, session); case PERF_RECORD_READ: - return curr_handler->process_read_event(event); + return ops->process_read_event(event, session); case PERF_RECORD_THROTTLE: - return curr_handler->process_throttle_event(event); + return ops->process_throttle_event(event, session); case PERF_RECORD_UNTHROTTLE: - return curr_handler->process_unthrottle_event(event); + return ops->process_unthrottle_event(event, session); default: - curr_handler->total_unknown++; + ops->total_unknown++; return -1; } } @@ -129,88 +125,58 @@ out: return err; } -int mmap_dispatch_perf_file(struct perf_header **pheader, - const char *input_name, - int force, - int full_paths, - int *cwdlen, - char **cwd) +static struct thread *perf_session__register_idle_thread(struct perf_session *self) +{ + struct thread *thread = perf_session__findnew(self, 0); + + if (!thread || thread__set_comm(thread, "swapper")) { + pr_err("problem inserting idle task.\n"); + thread = NULL; + } + + return thread; +} + +int perf_session__process_events(struct perf_session *self, + struct perf_event_ops *ops) { int err; - struct perf_header *header; unsigned long head, shift; unsigned long offset = 0; - struct stat input_stat; size_t page_size; - u64 sample_type; event_t *event; uint32_t size; - int input; char *buf; - if (curr_handler == NULL) { - pr_debug("Forgot to register perf file handler\n"); - return -EINVAL; - } - - page_size = getpagesize(); - - input = open(input_name, O_RDONLY); - if (input < 0) { - pr_err("Failed to open file: %s", input_name); - if (!strcmp(input_name, "perf.data")) - pr_err(" (try 'perf record' first)"); - pr_err("\n"); - return -errno; - } - - if (fstat(input, &input_stat) < 0) { - pr_err("failed to stat file"); - err = -errno; - goto out_close; - } - - err = -EACCES; - if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { - pr_err("file: %s not owned by current user or root\n", - input_name); - goto out_close; - } - - if (input_stat.st_size == 0) { - pr_info("zero-sized file, nothing to do!\n"); - goto done; - } + if (perf_session__register_idle_thread(self) == NULL) + return -ENOMEM; - err = -ENOMEM; - header = perf_header__new(); - if (header == NULL) - goto out_close; + perf_event_ops__fill_defaults(ops); - err = perf_header__read(header, input); - if (err < 0) - goto out_delete; - *pheader = header; - head = header->data_offset; + page_size = getpagesize(); - sample_type = perf_header__sample_type(header); + head = self->header.data_offset; + self->sample_type = perf_header__sample_type(&self->header); err = -EINVAL; - if (curr_handler->sample_type_check && - curr_handler->sample_type_check(sample_type) < 0) - goto out_delete; + if (ops->sample_type_check && ops->sample_type_check(self) < 0) + goto out_err; - if (!full_paths) { - if (getcwd(__cwd, sizeof(__cwd)) == NULL) { - pr_err("failed to get the current directory\n"); + if (!ops->full_paths) { + char bf[PATH_MAX]; + + if (getcwd(bf, sizeof(bf)) == NULL) { err = -errno; - goto out_delete; +out_getcwd_err: + pr_err("failed to get the current directory\n"); + goto out_err; + } + self->cwd = strdup(bf); + if (self->cwd == NULL) { + err = -ENOMEM; + goto out_getcwd_err; } - *cwd = __cwd; - *cwdlen = strlen(*cwd); - } else { - *cwd = NULL; - *cwdlen = 0; + self->cwdlen = strlen(self->cwd); } shift = page_size * (head / page_size); @@ -218,12 +184,12 @@ int mmap_dispatch_perf_file(struct perf_header **pheader, head -= shift; remap: - buf = mmap(NULL, page_size * mmap_window, PROT_READ, - MAP_SHARED, input, offset); + buf = mmap(NULL, page_size * self->mmap_window, PROT_READ, + MAP_SHARED, self->fd, offset); if (buf == MAP_FAILED) { pr_err("failed to mmap file\n"); err = -errno; - goto out_delete; + goto out_err; } more: @@ -233,12 +199,12 @@ more: if (!size) size = 8; - if (head + event->header.size >= page_size * mmap_window) { + if (head + event->header.size >= page_size * self->mmap_window) { int munmap_ret; shift = page_size * (head / page_size); - munmap_ret = munmap(buf, page_size * mmap_window); + munmap_ret = munmap(buf, page_size * self->mmap_window); assert(munmap_ret == 0); offset += shift; @@ -253,7 +219,7 @@ more: (void *)(long)event->header.size, event->header.type); - if (!size || process_event(event, offset, head) < 0) { + if (!size || process_event(event, self, ops, offset, head) < 0) { dump_printf("%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), @@ -273,19 +239,14 @@ more: head += size; - if (offset + head >= header->data_offset + header->data_size) + if (offset + head >= self->header.data_offset + self->header.data_size) goto done; - if (offset + head < (unsigned long)input_stat.st_size) + if (offset + head < self->size) goto more; done: err = 0; -out_close: - close(input); - +out_err: return err; -out_delete: - perf_header__delete(header); - goto out_close; } |