diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 09:30:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 09:30:52 -0700 |
commit | 4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9 (patch) | |
tree | 1f69733e5daab4915a76a41de0e4d1dc61e12cfb /tools/perf/util/session.c | |
parent | 3a3527b6461b1298cc53ce72f336346739297ac8 (diff) | |
parent | fc9ea5a1e53ee54f681e226d735008e2a6f8f470 (diff) | |
download | linux-4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9.tar.gz linux-4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9.tar.bz2 linux-4aed2fd8e3181fea7c09ba79cf64e7e3f4413bf9.zip |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (162 commits)
tracing/kprobes: unregister_trace_probe needs to be called under mutex
perf: expose event__process function
perf events: Fix mmap offset determination
perf, powerpc: fsl_emb: Restore setting perf_sample_data.period
perf, powerpc: Convert the FSL driver to use local64_t
perf tools: Don't keep unreferenced maps when unmaps are detected
perf session: Invalidate last_match when removing threads from rb_tree
perf session: Free the ref_reloc_sym memory at the right place
x86,mmiotrace: Add support for tracing STOS instruction
perf, sched migration: Librarize task states and event headers helpers
perf, sched migration: Librarize the GUI class
perf, sched migration: Make the GUI class client agnostic
perf, sched migration: Make it vertically scrollable
perf, sched migration: Parameterize cpu height and spacing
perf, sched migration: Fix key bindings
perf, sched migration: Ignore unhandled task states
perf, sched migration: Handle ignored migrate out events
perf: New migration tool overview
tracing: Drop cpparg() macro
perf: Use tracepoint_synchronize_unregister() to flush any pending tracepoint call
...
Fix up trivial conflicts in Makefile and drivers/cpufreq/cpufreq.c
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c422cd676313..fa9d652c2dc3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -27,8 +27,10 @@ static int perf_session__open(struct perf_session *self, bool force) self->fd = open(self->filename, O_RDONLY); if (self->fd < 0) { - pr_err("failed to open file: %s", self->filename); - if (!strcmp(self->filename, "perf.data")) + int err = errno; + + pr_err("failed to open %s: %s", self->filename, strerror(err)); + if (err == ENOENT && !strcmp(self->filename, "perf.data")) pr_err(" (try 'perf record' first)"); pr_err("\n"); return -errno; @@ -77,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self) return ret; } +static void perf_session__destroy_kernel_maps(struct perf_session *self) +{ + machine__destroy_kernel_maps(&self->host_machine); + machines__destroy_guest_kernel_maps(&self->machines); +} + struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) { size_t len = filename ? strlen(filename) + 1 : 0; @@ -94,8 +102,6 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc self->hists_tree = RB_ROOT; self->last_match = NULL; self->mmap_window = 32; - self->cwd = NULL; - self->cwdlen = 0; self->machines = RB_ROOT; self->repipe = repipe; INIT_LIST_HEAD(&self->ordered_samples.samples_head); @@ -124,16 +130,43 @@ out_delete: return NULL; } +static void perf_session__delete_dead_threads(struct perf_session *self) +{ + struct thread *n, *t; + + list_for_each_entry_safe(t, n, &self->dead_threads, node) { + list_del(&t->node); + thread__delete(t); + } +} + +static void perf_session__delete_threads(struct perf_session *self) +{ + struct rb_node *nd = rb_first(&self->threads); + + while (nd) { + struct thread *t = rb_entry(nd, struct thread, rb_node); + + rb_erase(&t->rb_node, &self->threads); + nd = rb_next(nd); + thread__delete(t); + } +} + void perf_session__delete(struct perf_session *self) { perf_header__exit(&self->header); + perf_session__destroy_kernel_maps(self); + perf_session__delete_dead_threads(self); + perf_session__delete_threads(self); + machine__exit(&self->host_machine); close(self->fd); - free(self->cwd); free(self); } void perf_session__remove_thread(struct perf_session *self, struct thread *th) { + self->last_match = NULL; rb_erase(&th->rb_node, &self->threads); /* * We may have references to this thread, for instance in some hist_entry @@ -830,23 +863,6 @@ int perf_session__process_events(struct perf_session *self, if (perf_session__register_idle_thread(self) == NULL) return -ENOMEM; - if (!symbol_conf.full_paths) { - char bf[PATH_MAX]; - - if (getcwd(bf, sizeof(bf)) == NULL) { - err = -errno; -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; - } - self->cwdlen = strlen(self->cwd); - } - if (!self->fd_pipe) err = __perf_session__process_events(self, self->header.data_offset, @@ -854,7 +870,7 @@ out_getcwd_err: self->size, ops); else err = __perf_session__process_pipe_events(self, ops); -out_err: + return err; } |