[PATCH 14/49] perf tools: Introduce thread__comm(_str)_by_time() helpers
From: Jiri Olsa
Date: Tue Jan 09 2018 - 10:46:49 EST
From: Namhyung Kim <namhyung@xxxxxxxxxx>
When data file indexing is enabled, it processes all task, comm and mmap
events first and then goes to the sample events. So all it sees is the
last comm of a thread although it has information at the time of sample.
Sort thread's comm by time so that it can find appropriate comm at the
sample time. The thread__comm_by_time() will mostly work even if
PERF_SAMPLE_TIME bit is off since in that case, sample->time will be
-1 so it'll take the last comm anyway.
Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Link: http://lkml.kernel.org/n/tip-g0q0o4prp0tj1zkb86in0dqu@xxxxxxxxxxxxxx
Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx>
---
tools/perf/util/thread.c | 33 ++++++++++++++++++++++++++++++++-
tools/perf/util/thread.h | 2 ++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 68b65b10579b..bf79a3ef06bc 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -192,6 +192,21 @@ struct comm *thread__exec_comm(const struct thread *thread)
return last;
}
+struct comm *thread__comm_by_time(const struct thread *thread, u64 timestamp)
+{
+ struct comm *comm;
+
+ list_for_each_entry(comm, &thread->comm_list, list) {
+ if (timestamp >= comm->start)
+ return comm;
+ }
+
+ if (list_empty(&thread->comm_list))
+ return NULL;
+
+ return list_last_entry(&thread->comm_list, struct comm, list);
+}
+
static int ____thread__set_comm(struct thread *thread, const char *str,
u64 timestamp, bool exec)
{
@@ -206,7 +221,13 @@ static int ____thread__set_comm(struct thread *thread, const char *str,
new = comm__new(str, timestamp, exec);
if (!new)
return -ENOMEM;
- list_add(&new->list, &thread->comm_list);
+
+ /* sort by time */
+ list_for_each_entry(curr, &thread->comm_list, list) {
+ if (timestamp >= curr->start)
+ break;
+ }
+ list_add_tail(&new->list, &curr->list);
if (exec)
unwind__flush_access(thread);
@@ -266,6 +287,16 @@ const char *thread__comm_str(const struct thread *thread)
return str;
}
+const char *thread__comm_str_by_time(const struct thread *thread, u64 timestamp)
+{
+ const struct comm *comm = thread__comm_by_time(thread, timestamp);
+
+ if (!comm)
+ return NULL;
+
+ return comm__str(comm);
+}
+
/* CHECKME: it should probably better return the max comm len from its comm list */
int thread__comm_len(struct thread *thread)
{
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 40cfa36c022a..cc670f02f9f2 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -86,8 +86,10 @@ int thread__set_comm_from_proc(struct thread *thread);
int thread__comm_len(struct thread *thread);
struct comm *thread__comm(const struct thread *thread);
struct comm *thread__exec_comm(const struct thread *thread);
+struct comm *thread__comm_by_time(const struct thread *thread, u64 timestamp);
const char *thread__comm_str(const struct thread *thread);
int thread__insert_map(struct thread *thread, struct map *map);
+const char *thread__comm_str_by_time(const struct thread *thread, u64 timestamp);
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
size_t thread__fprintf(struct thread *thread, FILE *fp);
--
2.13.6