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
)
23 if (cs
&& refcount_inc_not_zero(&cs
->refcnt
))
29 static void comm_str__put(struct comm_str
*cs
)
31 if (cs
&& refcount_dec_and_test(&cs
->refcnt
)) {
32 down_write(&comm_str_lock
);
33 rb_erase(&cs
->rb_node
, &comm_str_root
);
34 up_write(&comm_str_lock
);
40 static struct comm_str
*comm_str__alloc(const char *str
)
44 cs
= zalloc(sizeof(*cs
));
48 cs
->str
= strdup(str
);
54 refcount_set(&cs
->refcnt
, 1);
60 struct comm_str
*__comm_str__findnew(const char *str
, struct rb_root
*root
)
62 struct rb_node
**p
= &root
->rb_node
;
63 struct rb_node
*parent
= NULL
;
64 struct comm_str
*iter
, *new;
69 iter
= rb_entry(parent
, struct comm_str
, rb_node
);
72 * If we race with comm_str__put, iter->refcnt is 0
73 * and it will be removed within comm_str__put call
74 * shortly, ignore it in this search.
76 cmp
= strcmp(str
, iter
->str
);
77 if (!cmp
&& comm_str__get(iter
))
86 new = comm_str__alloc(str
);
90 rb_link_node(&new->rb_node
, parent
, p
);
91 rb_insert_color(&new->rb_node
, root
);
96 static struct comm_str
*comm_str__findnew(const char *str
, struct rb_root
*root
)
100 down_write(&comm_str_lock
);
101 cs
= __comm_str__findnew(str
, root
);
102 up_write(&comm_str_lock
);
107 struct comm
*comm__new(const char *str
, u64 timestamp
, bool exec
)
109 struct comm
*comm
= zalloc(sizeof(*comm
));
114 comm
->start
= timestamp
;
117 comm
->comm_str
= comm_str__findnew(str
, &comm_str_root
);
118 if (!comm
->comm_str
) {
126 int comm__override(struct comm
*comm
, const char *str
, u64 timestamp
, bool exec
)
128 struct comm_str
*new, *old
= comm
->comm_str
;
130 new = comm_str__findnew(str
, &comm_str_root
);
135 comm
->comm_str
= new;
136 comm
->start
= timestamp
;
143 void comm__free(struct comm
*comm
)
145 comm_str__put(comm
->comm_str
);
149 const char *comm__str(const struct comm
*comm
)
151 return comm
->comm_str
->str
;