1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/refcount.h>
13 struct rb_node rb_node
;
17 /* Should perhaps be moved to struct machine */
18 static struct rb_root comm_str_root
;
19 static struct rw_semaphore comm_str_lock
= {.lock
= PTHREAD_RWLOCK_INITIALIZER
,};
21 static struct comm_str
*comm_str__get(struct comm_str
*cs
)
24 refcount_inc(&cs
->refcnt
);
28 static void comm_str__put(struct comm_str
*cs
)
30 if (cs
&& refcount_dec_and_test(&cs
->refcnt
)) {
31 down_write(&comm_str_lock
);
32 rb_erase(&cs
->rb_node
, &comm_str_root
);
33 up_write(&comm_str_lock
);
39 static struct comm_str
*comm_str__alloc(const char *str
)
43 cs
= zalloc(sizeof(*cs
));
47 cs
->str
= strdup(str
);
53 refcount_set(&cs
->refcnt
, 1);
59 struct comm_str
*__comm_str__findnew(const char *str
, struct rb_root
*root
)
61 struct rb_node
**p
= &root
->rb_node
;
62 struct rb_node
*parent
= NULL
;
63 struct comm_str
*iter
, *new;
68 iter
= rb_entry(parent
, struct comm_str
, rb_node
);
70 cmp
= strcmp(str
, iter
->str
);
72 return comm_str__get(iter
);
80 new = comm_str__alloc(str
);
84 rb_link_node(&new->rb_node
, parent
, p
);
85 rb_insert_color(&new->rb_node
, root
);
90 static struct comm_str
*comm_str__findnew(const char *str
, struct rb_root
*root
)
94 down_write(&comm_str_lock
);
95 cs
= __comm_str__findnew(str
, root
);
96 up_write(&comm_str_lock
);
101 struct comm
*comm__new(const char *str
, u64 timestamp
, bool exec
)
103 struct comm
*comm
= zalloc(sizeof(*comm
));
108 comm
->start
= timestamp
;
111 comm
->comm_str
= comm_str__findnew(str
, &comm_str_root
);
112 if (!comm
->comm_str
) {
120 int comm__override(struct comm
*comm
, const char *str
, u64 timestamp
, bool exec
)
122 struct comm_str
*new, *old
= comm
->comm_str
;
124 new = comm_str__findnew(str
, &comm_str_root
);
129 comm
->comm_str
= new;
130 comm
->start
= timestamp
;
137 void comm__free(struct comm
*comm
)
139 comm_str__put(comm
->comm_str
);
143 const char *comm__str(const struct comm
*comm
)
145 return comm
->comm_str
->str
;