11 struct thread *thread__new(pid_t pid, pid_t tid)
15 struct thread *thread = zalloc(sizeof(*thread));
18 thread->mg = map_groups__new();
19 if (thread->mg == NULL)
25 INIT_LIST_HEAD(&thread->comm_list);
27 comm_str = malloc(32);
31 snprintf(comm_str, 32, ":%d", tid);
32 comm = comm__new(comm_str, 0);
37 list_add(&comm->list, &thread->comm_list);
43 map_groups__delete(thread->mg);
49 void thread__delete(struct thread *thread)
51 struct comm *comm, *tmp;
53 map_groups__put(thread->mg);
55 list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
56 list_del(&comm->list);
63 struct comm *thread__comm(const struct thread *thread)
65 if (list_empty(&thread->comm_list))
68 return list_first_entry(&thread->comm_list, struct comm, list);
71 /* CHECKME: time should always be 0 if event aren't ordered */
72 int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
74 struct comm *new, *curr = thread__comm(thread);
77 /* Override latest entry if it had no specific time coverage */
79 err = comm__override(curr, str, timestamp);
83 new = comm__new(str, timestamp);
86 list_add(&new->list, &thread->comm_list);
89 thread->comm_set = true;
94 const char *thread__comm_str(const struct thread *thread)
96 const struct comm *comm = thread__comm(thread);
101 return comm__str(comm);
104 /* CHECKME: it should probably better return the max comm len from its comm list */
105 int thread__comm_len(struct thread *thread)
107 if (!thread->comm_len) {
108 const char *comm = thread__comm_str(thread);
111 thread->comm_len = strlen(comm);
114 return thread->comm_len;
117 size_t thread__fprintf(struct thread *thread, FILE *fp)
119 return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
120 map_groups__fprintf(thread->mg, verbose, fp);
123 void thread__insert_map(struct thread *thread, struct map *map)
125 map_groups__fixup_overlappings(thread->mg, map, verbose, stderr);
126 map_groups__insert(thread->mg, map);
129 int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
133 if (parent->comm_set) {
134 const char *comm = thread__comm_str(parent);
137 err = thread__set_comm(thread, comm, timestamp);
140 thread->comm_set = true;
143 for (i = 0; i < MAP__NR_TYPES; ++i)
144 if (map_groups__clone(thread->mg, parent->mg, i) < 0)
147 thread->ppid = parent->tid;
152 void thread__find_cpumode_addr_location(struct thread *thread,
153 struct machine *machine,
154 enum map_type type, u64 addr,
155 struct addr_location *al)
158 const u8 const cpumodes[] = {
159 PERF_RECORD_MISC_USER,
160 PERF_RECORD_MISC_KERNEL,
161 PERF_RECORD_MISC_GUEST_USER,
162 PERF_RECORD_MISC_GUEST_KERNEL
165 for (i = 0; i < ARRAY_SIZE(cpumodes); i++) {
166 thread__find_addr_location(thread, machine, cpumodes[i], type,