xref: /openbmc/linux/tools/perf/util/comm.c (revision 1902efe7f626fdebe1520f5ff11f1309ec506708)
1*1902efe7SFrederic Weisbecker #include "comm.h"
2*1902efe7SFrederic Weisbecker #include "util.h"
3*1902efe7SFrederic Weisbecker #include <stdlib.h>
4*1902efe7SFrederic Weisbecker #include <stdio.h>
5*1902efe7SFrederic Weisbecker 
6*1902efe7SFrederic Weisbecker struct comm_str {
7*1902efe7SFrederic Weisbecker 	char *str;
8*1902efe7SFrederic Weisbecker 	struct rb_node rb_node;
9*1902efe7SFrederic Weisbecker 	int ref;
10*1902efe7SFrederic Weisbecker };
11*1902efe7SFrederic Weisbecker 
12*1902efe7SFrederic Weisbecker /* Should perhaps be moved to struct machine */
13*1902efe7SFrederic Weisbecker static struct rb_root comm_str_root;
14*1902efe7SFrederic Weisbecker 
15*1902efe7SFrederic Weisbecker static void comm_str__get(struct comm_str *cs)
16*1902efe7SFrederic Weisbecker {
17*1902efe7SFrederic Weisbecker 	cs->ref++;
18*1902efe7SFrederic Weisbecker }
19*1902efe7SFrederic Weisbecker 
20*1902efe7SFrederic Weisbecker static void comm_str__put(struct comm_str *cs)
21*1902efe7SFrederic Weisbecker {
22*1902efe7SFrederic Weisbecker 	if (!--cs->ref) {
23*1902efe7SFrederic Weisbecker 		rb_erase(&cs->rb_node, &comm_str_root);
24*1902efe7SFrederic Weisbecker 		free(cs->str);
25*1902efe7SFrederic Weisbecker 		free(cs);
26*1902efe7SFrederic Weisbecker 	}
27*1902efe7SFrederic Weisbecker }
28*1902efe7SFrederic Weisbecker 
29*1902efe7SFrederic Weisbecker static struct comm_str *comm_str__alloc(const char *str)
30*1902efe7SFrederic Weisbecker {
31*1902efe7SFrederic Weisbecker 	struct comm_str *cs;
32*1902efe7SFrederic Weisbecker 
33*1902efe7SFrederic Weisbecker 	cs = zalloc(sizeof(*cs));
34*1902efe7SFrederic Weisbecker 	if (!cs)
35*1902efe7SFrederic Weisbecker 		return NULL;
36*1902efe7SFrederic Weisbecker 
37*1902efe7SFrederic Weisbecker 	cs->str = strdup(str);
38*1902efe7SFrederic Weisbecker 	if (!cs->str) {
39*1902efe7SFrederic Weisbecker 		free(cs);
40*1902efe7SFrederic Weisbecker 		return NULL;
41*1902efe7SFrederic Weisbecker 	}
42*1902efe7SFrederic Weisbecker 
43*1902efe7SFrederic Weisbecker 	return cs;
44*1902efe7SFrederic Weisbecker }
45*1902efe7SFrederic Weisbecker 
46*1902efe7SFrederic Weisbecker static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
47*1902efe7SFrederic Weisbecker {
48*1902efe7SFrederic Weisbecker 	struct rb_node **p = &root->rb_node;
49*1902efe7SFrederic Weisbecker 	struct rb_node *parent = NULL;
50*1902efe7SFrederic Weisbecker 	struct comm_str *iter, *new;
51*1902efe7SFrederic Weisbecker 	int cmp;
52*1902efe7SFrederic Weisbecker 
53*1902efe7SFrederic Weisbecker 	while (*p != NULL) {
54*1902efe7SFrederic Weisbecker 		parent = *p;
55*1902efe7SFrederic Weisbecker 		iter = rb_entry(parent, struct comm_str, rb_node);
56*1902efe7SFrederic Weisbecker 
57*1902efe7SFrederic Weisbecker 		cmp = strcmp(str, iter->str);
58*1902efe7SFrederic Weisbecker 		if (!cmp)
59*1902efe7SFrederic Weisbecker 			return iter;
60*1902efe7SFrederic Weisbecker 
61*1902efe7SFrederic Weisbecker 		if (cmp < 0)
62*1902efe7SFrederic Weisbecker 			p = &(*p)->rb_left;
63*1902efe7SFrederic Weisbecker 		else
64*1902efe7SFrederic Weisbecker 			p = &(*p)->rb_right;
65*1902efe7SFrederic Weisbecker 	}
66*1902efe7SFrederic Weisbecker 
67*1902efe7SFrederic Weisbecker 	new = comm_str__alloc(str);
68*1902efe7SFrederic Weisbecker 	if (!new)
69*1902efe7SFrederic Weisbecker 		return NULL;
70*1902efe7SFrederic Weisbecker 
71*1902efe7SFrederic Weisbecker 	rb_link_node(&new->rb_node, parent, p);
72*1902efe7SFrederic Weisbecker 	rb_insert_color(&new->rb_node, root);
73*1902efe7SFrederic Weisbecker 
74*1902efe7SFrederic Weisbecker 	return new;
75*1902efe7SFrederic Weisbecker }
76*1902efe7SFrederic Weisbecker 
77*1902efe7SFrederic Weisbecker struct comm *comm__new(const char *str, u64 timestamp)
78*1902efe7SFrederic Weisbecker {
79*1902efe7SFrederic Weisbecker 	struct comm *comm = zalloc(sizeof(*comm));
80*1902efe7SFrederic Weisbecker 
81*1902efe7SFrederic Weisbecker 	if (!comm)
82*1902efe7SFrederic Weisbecker 		return NULL;
83*1902efe7SFrederic Weisbecker 
84*1902efe7SFrederic Weisbecker 	comm->start = timestamp;
85*1902efe7SFrederic Weisbecker 
86*1902efe7SFrederic Weisbecker 	comm->comm_str = comm_str__findnew(str, &comm_str_root);
87*1902efe7SFrederic Weisbecker 	if (!comm->comm_str) {
88*1902efe7SFrederic Weisbecker 		free(comm);
89*1902efe7SFrederic Weisbecker 		return NULL;
90*1902efe7SFrederic Weisbecker 	}
91*1902efe7SFrederic Weisbecker 
92*1902efe7SFrederic Weisbecker 	comm_str__get(comm->comm_str);
93*1902efe7SFrederic Weisbecker 
94*1902efe7SFrederic Weisbecker 	return comm;
95*1902efe7SFrederic Weisbecker }
96*1902efe7SFrederic Weisbecker 
97*1902efe7SFrederic Weisbecker void comm__free(struct comm *comm)
98*1902efe7SFrederic Weisbecker {
99*1902efe7SFrederic Weisbecker 	comm_str__put(comm->comm_str);
100*1902efe7SFrederic Weisbecker 	free(comm);
101*1902efe7SFrederic Weisbecker }
102*1902efe7SFrederic Weisbecker 
103*1902efe7SFrederic Weisbecker const char *comm__str(const struct comm *comm)
104*1902efe7SFrederic Weisbecker {
105*1902efe7SFrederic Weisbecker 	return comm->comm_str->str;
106*1902efe7SFrederic Weisbecker }
107