]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - tools/perf/util/data_map.c
Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6
[mv-sheeva.git] / tools / perf / util / data_map.c
index ca0bedf637c243135d40ffafc41562aa3a047c7d..b557b836de3dca6e44543d7b851b62ff9cc42546 100644 (file)
@@ -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,34 +73,34 @@ 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;
        }
 }
 
-int perf_header__read_build_ids(int input, off_t offset, off_t size)
+int perf_header__read_build_ids(int input, u64 offset, u64 size)
 {
        struct build_id_event bev;
        char filename[PATH_MAX];
-       off_t limit = offset + size;
+       u64 limit = offset + size;
        int err = -1;
 
        while (offset < limit) {
@@ -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;
 }