diff options
Diffstat (limited to 'tools/perf/util/thread.c')
-rw-r--r-- | tools/perf/util/thread.c | 137 |
1 files changed, 94 insertions, 43 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index e3d4a550a703..cd8e2f592719 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -6,86 +6,137 @@ | |||
6 | #include "thread.h" | 6 | #include "thread.h" |
7 | #include "util.h" | 7 | #include "util.h" |
8 | #include "debug.h" | 8 | #include "debug.h" |
9 | #include "comm.h" | ||
9 | 10 | ||
10 | struct thread *thread__new(pid_t pid, pid_t tid) | 11 | struct thread *thread__new(pid_t pid, pid_t tid) |
11 | { | 12 | { |
12 | struct thread *self = zalloc(sizeof(*self)); | 13 | char *comm_str; |
13 | 14 | struct comm *comm; | |
14 | if (self != NULL) { | 15 | struct thread *thread = zalloc(sizeof(*thread)); |
15 | map_groups__init(&self->mg); | 16 | |
16 | self->pid_ = pid; | 17 | if (thread != NULL) { |
17 | self->tid = tid; | 18 | map_groups__init(&thread->mg); |
18 | self->ppid = -1; | 19 | thread->pid_ = pid; |
19 | self->comm = malloc(32); | 20 | thread->tid = tid; |
20 | if (self->comm) | 21 | thread->ppid = -1; |
21 | snprintf(self->comm, 32, ":%d", self->tid); | 22 | INIT_LIST_HEAD(&thread->comm_list); |
23 | |||
24 | comm_str = malloc(32); | ||
25 | if (!comm_str) | ||
26 | goto err_thread; | ||
27 | |||
28 | snprintf(comm_str, 32, ":%d", tid); | ||
29 | comm = comm__new(comm_str, 0); | ||
30 | free(comm_str); | ||
31 | if (!comm) | ||
32 | goto err_thread; | ||
33 | |||
34 | list_add(&comm->list, &thread->comm_list); | ||
35 | } | ||
36 | |||
37 | return thread; | ||
38 | |||
39 | err_thread: | ||
40 | free(thread); | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | void thread__delete(struct thread *thread) | ||
45 | { | ||
46 | struct comm *comm, *tmp; | ||
47 | |||
48 | map_groups__exit(&thread->mg); | ||
49 | list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) { | ||
50 | list_del(&comm->list); | ||
51 | comm__free(comm); | ||
22 | } | 52 | } |
23 | 53 | ||
24 | return self; | 54 | free(thread); |
25 | } | 55 | } |
26 | 56 | ||
27 | void thread__delete(struct thread *self) | 57 | struct comm *thread__comm(const struct thread *thread) |
28 | { | 58 | { |
29 | map_groups__exit(&self->mg); | 59 | if (list_empty(&thread->comm_list)) |
30 | free(self->comm); | 60 | return NULL; |
31 | free(self); | 61 | |
62 | return list_first_entry(&thread->comm_list, struct comm, list); | ||
32 | } | 63 | } |
33 | 64 | ||
34 | int thread__set_comm(struct thread *self, const char *comm) | 65 | /* CHECKME: time should always be 0 if event aren't ordered */ |
66 | int thread__set_comm(struct thread *thread, const char *str, u64 timestamp) | ||
35 | { | 67 | { |
36 | int err; | 68 | struct comm *new, *curr = thread__comm(thread); |
37 | 69 | ||
38 | if (self->comm) | 70 | /* Override latest entry if it had no specific time coverage */ |
39 | free(self->comm); | 71 | if (!curr->start) { |
40 | self->comm = strdup(comm); | 72 | comm__override(curr, str, timestamp); |
41 | err = self->comm == NULL ? -ENOMEM : 0; | 73 | return 0; |
42 | if (!err) { | ||
43 | self->comm_set = true; | ||
44 | } | 74 | } |
45 | return err; | 75 | |
76 | new = comm__new(str, timestamp); | ||
77 | if (!new) | ||
78 | return -ENOMEM; | ||
79 | |||
80 | list_add(&new->list, &thread->comm_list); | ||
81 | thread->comm_set = true; | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | const char *thread__comm_str(const struct thread *thread) | ||
87 | { | ||
88 | const struct comm *comm = thread__comm(thread); | ||
89 | |||
90 | if (!comm) | ||
91 | return NULL; | ||
92 | |||
93 | return comm__str(comm); | ||
46 | } | 94 | } |
47 | 95 | ||
48 | int thread__comm_len(struct thread *self) | 96 | /* CHECKME: it should probably better return the max comm len from its comm list */ |
97 | int thread__comm_len(struct thread *thread) | ||
49 | { | 98 | { |
50 | if (!self->comm_len) { | 99 | if (!thread->comm_len) { |
51 | if (!self->comm) | 100 | const char *comm = thread__comm_str(thread); |
101 | if (!comm) | ||
52 | return 0; | 102 | return 0; |
53 | self->comm_len = strlen(self->comm); | 103 | thread->comm_len = strlen(comm); |
54 | } | 104 | } |
55 | 105 | ||
56 | return self->comm_len; | 106 | return thread->comm_len; |
57 | } | 107 | } |
58 | 108 | ||
59 | size_t thread__fprintf(struct thread *thread, FILE *fp) | 109 | size_t thread__fprintf(struct thread *thread, FILE *fp) |
60 | { | 110 | { |
61 | return fprintf(fp, "Thread %d %s\n", thread->tid, thread->comm) + | 111 | return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) + |
62 | map_groups__fprintf(&thread->mg, verbose, fp); | 112 | map_groups__fprintf(&thread->mg, verbose, fp); |
63 | } | 113 | } |
64 | 114 | ||
65 | void thread__insert_map(struct thread *self, struct map *map) | 115 | void thread__insert_map(struct thread *thread, struct map *map) |
66 | { | 116 | { |
67 | map_groups__fixup_overlappings(&self->mg, map, verbose, stderr); | 117 | map_groups__fixup_overlappings(&thread->mg, map, verbose, stderr); |
68 | map_groups__insert(&self->mg, map); | 118 | map_groups__insert(&thread->mg, map); |
69 | } | 119 | } |
70 | 120 | ||
71 | int thread__fork(struct thread *self, struct thread *parent) | 121 | int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) |
72 | { | 122 | { |
73 | int i; | 123 | int i, err; |
74 | 124 | ||
75 | if (parent->comm_set) { | 125 | if (parent->comm_set) { |
76 | if (self->comm) | 126 | const char *comm = thread__comm_str(parent); |
77 | free(self->comm); | 127 | if (!comm) |
78 | self->comm = strdup(parent->comm); | ||
79 | if (!self->comm) | ||
80 | return -ENOMEM; | 128 | return -ENOMEM; |
81 | self->comm_set = true; | 129 | err = thread__set_comm(thread, comm, timestamp); |
130 | if (!err) | ||
131 | return err; | ||
132 | thread->comm_set = true; | ||
82 | } | 133 | } |
83 | 134 | ||
84 | for (i = 0; i < MAP__NR_TYPES; ++i) | 135 | for (i = 0; i < MAP__NR_TYPES; ++i) |
85 | if (map_groups__clone(&self->mg, &parent->mg, i) < 0) | 136 | if (map_groups__clone(&thread->mg, &parent->mg, i) < 0) |
86 | return -ENOMEM; | 137 | return -ENOMEM; |
87 | 138 | ||
88 | self->ppid = parent->tid; | 139 | thread->ppid = parent->tid; |
89 | 140 | ||
90 | return 0; | 141 | return 0; |
91 | } | 142 | } |