xref: /openbmc/linux/tools/perf/util/thread.c (revision b9c5143a012a543c4ee872498d6dbae5c10beb2e)
16baa0a5aSFrederic Weisbecker #include "../perf.h"
26baa0a5aSFrederic Weisbecker #include <stdlib.h>
36baa0a5aSFrederic Weisbecker #include <stdio.h>
46baa0a5aSFrederic Weisbecker #include <string.h>
5b3165f41SArnaldo Carvalho de Melo #include "session.h"
66baa0a5aSFrederic Weisbecker #include "thread.h"
76baa0a5aSFrederic Weisbecker #include "util.h"
86e086437SFrederic Weisbecker #include "debug.h"
96baa0a5aSFrederic Weisbecker 
1099d725fcSAdrian Hunter struct thread *thread__new(pid_t pid, pid_t tid)
116baa0a5aSFrederic Weisbecker {
12c824c433SArnaldo Carvalho de Melo 	struct thread *thread = zalloc(sizeof(*thread));
136baa0a5aSFrederic Weisbecker 
14c824c433SArnaldo Carvalho de Melo 	if (thread != NULL) {
15c824c433SArnaldo Carvalho de Melo 		map_groups__init(&thread->mg);
16c824c433SArnaldo Carvalho de Melo 		thread->pid_ = pid;
17c824c433SArnaldo Carvalho de Melo 		thread->tid = tid;
18c824c433SArnaldo Carvalho de Melo 		thread->ppid = -1;
19c824c433SArnaldo Carvalho de Melo 		thread->comm = malloc(32);
20c824c433SArnaldo Carvalho de Melo 		if (thread->comm)
21c824c433SArnaldo Carvalho de Melo 			snprintf(thread->comm, 32, ":%d", thread->tid);
226baa0a5aSFrederic Weisbecker 	}
236baa0a5aSFrederic Weisbecker 
24c824c433SArnaldo Carvalho de Melo 	return thread;
256baa0a5aSFrederic Weisbecker }
266baa0a5aSFrederic Weisbecker 
27c824c433SArnaldo Carvalho de Melo void thread__delete(struct thread *thread)
28591765fdSArnaldo Carvalho de Melo {
29c824c433SArnaldo Carvalho de Melo 	map_groups__exit(&thread->mg);
30c824c433SArnaldo Carvalho de Melo 	free(thread->comm);
31c824c433SArnaldo Carvalho de Melo 	free(thread);
32591765fdSArnaldo Carvalho de Melo }
33591765fdSArnaldo Carvalho de Melo 
34c824c433SArnaldo Carvalho de Melo int thread__set_comm(struct thread *thread, const char *comm)
356baa0a5aSFrederic Weisbecker {
364385d580SDavid S. Miller 	int err;
374385d580SDavid S. Miller 
38c824c433SArnaldo Carvalho de Melo 	if (thread->comm)
39c824c433SArnaldo Carvalho de Melo 		free(thread->comm);
40c824c433SArnaldo Carvalho de Melo 	thread->comm = strdup(comm);
41c824c433SArnaldo Carvalho de Melo 	err = thread->comm == NULL ? -ENOMEM : 0;
424385d580SDavid S. Miller 	if (!err) {
43c824c433SArnaldo Carvalho de Melo 		thread->comm_set = true;
444385d580SDavid S. Miller 	}
454385d580SDavid S. Miller 	return err;
466baa0a5aSFrederic Weisbecker }
476baa0a5aSFrederic Weisbecker 
48*b9c5143aSFrederic Weisbecker const char *thread__comm_str(const struct thread *thread)
49*b9c5143aSFrederic Weisbecker {
50*b9c5143aSFrederic Weisbecker 	return thread->comm;
51*b9c5143aSFrederic Weisbecker }
52*b9c5143aSFrederic Weisbecker 
53c824c433SArnaldo Carvalho de Melo int thread__comm_len(struct thread *thread)
54a4fb581bSFrederic Weisbecker {
55c824c433SArnaldo Carvalho de Melo 	if (!thread->comm_len) {
56c824c433SArnaldo Carvalho de Melo 		if (!thread->comm)
57a4fb581bSFrederic Weisbecker 			return 0;
58c824c433SArnaldo Carvalho de Melo 		thread->comm_len = strlen(thread->comm);
59a4fb581bSFrederic Weisbecker 	}
60a4fb581bSFrederic Weisbecker 
61c824c433SArnaldo Carvalho de Melo 	return thread->comm_len;
62a4fb581bSFrederic Weisbecker }
63a4fb581bSFrederic Weisbecker 
643f067dcaSArnaldo Carvalho de Melo size_t thread__fprintf(struct thread *thread, FILE *fp)
6595011c60SArnaldo Carvalho de Melo {
66*b9c5143aSFrederic Weisbecker 	return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
673f067dcaSArnaldo Carvalho de Melo 	       map_groups__fprintf(&thread->mg, verbose, fp);
686baa0a5aSFrederic Weisbecker }
696baa0a5aSFrederic Weisbecker 
70c824c433SArnaldo Carvalho de Melo void thread__insert_map(struct thread *thread, struct map *map)
711b46cddfSArnaldo Carvalho de Melo {
72c824c433SArnaldo Carvalho de Melo 	map_groups__fixup_overlappings(&thread->mg, map, verbose, stderr);
73c824c433SArnaldo Carvalho de Melo 	map_groups__insert(&thread->mg, map);
7495011c60SArnaldo Carvalho de Melo }
7595011c60SArnaldo Carvalho de Melo 
76c824c433SArnaldo Carvalho de Melo int thread__fork(struct thread *thread, struct thread *parent)
776baa0a5aSFrederic Weisbecker {
7895011c60SArnaldo Carvalho de Melo 	int i;
796baa0a5aSFrederic Weisbecker 
80faa5c5c3SArnaldo Carvalho de Melo 	if (parent->comm_set) {
81c824c433SArnaldo Carvalho de Melo 		if (thread->comm)
82c824c433SArnaldo Carvalho de Melo 			free(thread->comm);
83c824c433SArnaldo Carvalho de Melo 		thread->comm = strdup(parent->comm);
84c824c433SArnaldo Carvalho de Melo 		if (!thread->comm)
856baa0a5aSFrederic Weisbecker 			return -ENOMEM;
86c824c433SArnaldo Carvalho de Melo 		thread->comm_set = true;
87faa5c5c3SArnaldo Carvalho de Melo 	}
886baa0a5aSFrederic Weisbecker 
8995011c60SArnaldo Carvalho de Melo 	for (i = 0; i < MAP__NR_TYPES; ++i)
90c824c433SArnaldo Carvalho de Melo 		if (map_groups__clone(&thread->mg, &parent->mg, i) < 0)
916baa0a5aSFrederic Weisbecker 			return -ENOMEM;
9270c57efbSDavid Ahern 
93c824c433SArnaldo Carvalho de Melo 	thread->ppid = parent->tid;
9470c57efbSDavid Ahern 
956baa0a5aSFrederic Weisbecker 	return 0;
966baa0a5aSFrederic Weisbecker }
97