xref: /linux-6.15/tools/perf/util/thread.c (revision 9d2f8e22)
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 
10*9d2f8e22SArnaldo Carvalho de Melo struct thread *thread__new(pid_t pid)
116baa0a5aSFrederic Weisbecker {
1236479484SArnaldo Carvalho de Melo 	struct thread *self = zalloc(sizeof(*self));
136baa0a5aSFrederic Weisbecker 
146baa0a5aSFrederic Weisbecker 	if (self != NULL) {
159958e1f0SArnaldo Carvalho de Melo 		map_groups__init(&self->mg);
169958e1f0SArnaldo Carvalho de Melo 		self->pid = pid;
176baa0a5aSFrederic Weisbecker 		self->comm = malloc(32);
186baa0a5aSFrederic Weisbecker 		if (self->comm)
196baa0a5aSFrederic Weisbecker 			snprintf(self->comm, 32, ":%d", self->pid);
206baa0a5aSFrederic Weisbecker 	}
216baa0a5aSFrederic Weisbecker 
226baa0a5aSFrederic Weisbecker 	return self;
236baa0a5aSFrederic Weisbecker }
246baa0a5aSFrederic Weisbecker 
25591765fdSArnaldo Carvalho de Melo void thread__delete(struct thread *self)
26591765fdSArnaldo Carvalho de Melo {
27591765fdSArnaldo Carvalho de Melo 	map_groups__exit(&self->mg);
28591765fdSArnaldo Carvalho de Melo 	free(self->comm);
29591765fdSArnaldo Carvalho de Melo 	free(self);
30591765fdSArnaldo Carvalho de Melo }
31591765fdSArnaldo Carvalho de Melo 
326baa0a5aSFrederic Weisbecker int thread__set_comm(struct thread *self, const char *comm)
336baa0a5aSFrederic Weisbecker {
344385d580SDavid S. Miller 	int err;
354385d580SDavid S. Miller 
366baa0a5aSFrederic Weisbecker 	if (self->comm)
376baa0a5aSFrederic Weisbecker 		free(self->comm);
386baa0a5aSFrederic Weisbecker 	self->comm = strdup(comm);
394385d580SDavid S. Miller 	err = self->comm == NULL ? -ENOMEM : 0;
404385d580SDavid S. Miller 	if (!err) {
41faa5c5c3SArnaldo Carvalho de Melo 		self->comm_set = true;
424385d580SDavid S. Miller 		map_groups__flush(&self->mg);
434385d580SDavid S. Miller 	}
444385d580SDavid S. Miller 	return err;
456baa0a5aSFrederic Weisbecker }
466baa0a5aSFrederic Weisbecker 
47a4fb581bSFrederic Weisbecker int thread__comm_len(struct thread *self)
48a4fb581bSFrederic Weisbecker {
49a4fb581bSFrederic Weisbecker 	if (!self->comm_len) {
50a4fb581bSFrederic Weisbecker 		if (!self->comm)
51a4fb581bSFrederic Weisbecker 			return 0;
52a4fb581bSFrederic Weisbecker 		self->comm_len = strlen(self->comm);
53a4fb581bSFrederic Weisbecker 	}
54a4fb581bSFrederic Weisbecker 
55a4fb581bSFrederic Weisbecker 	return self->comm_len;
56a4fb581bSFrederic Weisbecker }
57a4fb581bSFrederic Weisbecker 
5895011c60SArnaldo Carvalho de Melo static size_t thread__fprintf(struct thread *self, FILE *fp)
5995011c60SArnaldo Carvalho de Melo {
609958e1f0SArnaldo Carvalho de Melo 	return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) +
61c6e718ffSArnaldo Carvalho de Melo 	       map_groups__fprintf(&self->mg, verbose, fp);
626baa0a5aSFrederic Weisbecker }
636baa0a5aSFrederic Weisbecker 
641b46cddfSArnaldo Carvalho de Melo void thread__insert_map(struct thread *self, struct map *map)
651b46cddfSArnaldo Carvalho de Melo {
66c6e718ffSArnaldo Carvalho de Melo 	map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
679958e1f0SArnaldo Carvalho de Melo 	map_groups__insert(&self->mg, map);
6895011c60SArnaldo Carvalho de Melo }
6995011c60SArnaldo Carvalho de Melo 
706baa0a5aSFrederic Weisbecker int thread__fork(struct thread *self, struct thread *parent)
716baa0a5aSFrederic Weisbecker {
7295011c60SArnaldo Carvalho de Melo 	int i;
736baa0a5aSFrederic Weisbecker 
74faa5c5c3SArnaldo Carvalho de Melo 	if (parent->comm_set) {
756baa0a5aSFrederic Weisbecker 		if (self->comm)
766baa0a5aSFrederic Weisbecker 			free(self->comm);
776baa0a5aSFrederic Weisbecker 		self->comm = strdup(parent->comm);
786baa0a5aSFrederic Weisbecker 		if (!self->comm)
796baa0a5aSFrederic Weisbecker 			return -ENOMEM;
80faa5c5c3SArnaldo Carvalho de Melo 		self->comm_set = true;
81faa5c5c3SArnaldo Carvalho de Melo 	}
826baa0a5aSFrederic Weisbecker 
8395011c60SArnaldo Carvalho de Melo 	for (i = 0; i < MAP__NR_TYPES; ++i)
849958e1f0SArnaldo Carvalho de Melo 		if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
856baa0a5aSFrederic Weisbecker 			return -ENOMEM;
866baa0a5aSFrederic Weisbecker 	return 0;
876baa0a5aSFrederic Weisbecker }
886baa0a5aSFrederic Weisbecker 
89b424eba2SArnaldo Carvalho de Melo size_t machine__fprintf(struct machine *machine, FILE *fp)
906baa0a5aSFrederic Weisbecker {
916baa0a5aSFrederic Weisbecker 	size_t ret = 0;
926baa0a5aSFrederic Weisbecker 	struct rb_node *nd;
936baa0a5aSFrederic Weisbecker 
94b424eba2SArnaldo Carvalho de Melo 	for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
956baa0a5aSFrederic Weisbecker 		struct thread *pos = rb_entry(nd, struct thread, rb_node);
966baa0a5aSFrederic Weisbecker 
976baa0a5aSFrederic Weisbecker 		ret += thread__fprintf(pos, fp);
986baa0a5aSFrederic Weisbecker 	}
996baa0a5aSFrederic Weisbecker 
1006baa0a5aSFrederic Weisbecker 	return ret;
1016baa0a5aSFrederic Weisbecker }
102