Linux Perf
comm.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 #include "comm.h"
3 #include "util.h"
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <linux/refcount.h>
9 #include "rwsem.h"
10 
11 struct comm_str {
12  char *str;
13  struct rb_node rb_node;
14  refcount_t refcnt;
15 };
16 
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,};
20 
21 static struct comm_str *comm_str__get(struct comm_str *cs)
22 {
23  if (cs)
24  refcount_inc(&cs->refcnt);
25  return cs;
26 }
27 
28 static void comm_str__put(struct comm_str *cs)
29 {
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);
34  zfree(&cs->str);
35  free(cs);
36  }
37 }
38 
39 static struct comm_str *comm_str__alloc(const char *str)
40 {
41  struct comm_str *cs;
42 
43  cs = zalloc(sizeof(*cs));
44  if (!cs)
45  return NULL;
46 
47  cs->str = strdup(str);
48  if (!cs->str) {
49  free(cs);
50  return NULL;
51  }
52 
53  refcount_set(&cs->refcnt, 1);
54 
55  return cs;
56 }
57 
58 static
59 struct comm_str *__comm_str__findnew(const char *str, struct rb_root *root)
60 {
61  struct rb_node **p = &root->rb_node;
62  struct rb_node *parent = NULL;
63  struct comm_str *iter, *new;
64  int cmp;
65 
66  while (*p != NULL) {
67  parent = *p;
68  iter = rb_entry(parent, struct comm_str, rb_node);
69 
70  cmp = strcmp(str, iter->str);
71  if (!cmp)
72  return comm_str__get(iter);
73 
74  if (cmp < 0)
75  p = &(*p)->rb_left;
76  else
77  p = &(*p)->rb_right;
78  }
79 
80  new = comm_str__alloc(str);
81  if (!new)
82  return NULL;
83 
84  rb_link_node(&new->rb_node, parent, p);
85  rb_insert_color(&new->rb_node, root);
86 
87  return new;
88 }
89 
90 static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
91 {
92  struct comm_str *cs;
93 
94  down_write(&comm_str_lock);
95  cs = __comm_str__findnew(str, root);
96  up_write(&comm_str_lock);
97 
98  return cs;
99 }
100 
101 struct comm *comm__new(const char *str, u64 timestamp, bool exec)
102 {
103  struct comm *comm = zalloc(sizeof(*comm));
104 
105  if (!comm)
106  return NULL;
107 
108  comm->start = timestamp;
109  comm->exec = exec;
110 
112  if (!comm->comm_str) {
113  free(comm);
114  return NULL;
115  }
116 
117  return comm;
118 }
119 
120 int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
121 {
122  struct comm_str *new, *old = comm->comm_str;
123 
124  new = comm_str__findnew(str, &comm_str_root);
125  if (!new)
126  return -ENOMEM;
127 
128  comm_str__put(old);
129  comm->comm_str = new;
130  comm->start = timestamp;
131  if (exec)
132  comm->exec = true;
133 
134  return 0;
135 }
136 
137 void comm__free(struct comm *comm)
138 {
139  comm_str__put(comm->comm_str);
140  free(comm);
141 }
142 
143 const char *comm__str(const struct comm *comm)
144 {
145  return comm->comm_str->str;
146 }
const char * comm
Definition: hists_common.c:16
struct comm * comm__new(const char *str, u64 timestamp, bool exec)
Definition: comm.c:101
char * str
Definition: comm.c:12
pthread_rwlock_t lock
Definition: rwsem.h:7
struct rb_root root
Definition: block-range.c:6
static struct comm_str * comm_str__get(struct comm_str *cs)
Definition: comm.c:21
static struct rw_semaphore comm_str_lock
Definition: comm.c:19
static void comm_str__put(struct comm_str *cs)
Definition: comm.c:28
static struct comm_str * comm_str__findnew(const char *str, struct rb_root *root)
Definition: comm.c:90
int up_write(struct rw_semaphore *sem)
Definition: rwsem.c:29
struct rb_node rb_node
Definition: comm.c:13
Definition: comm.h:11
u64 start
Definition: comm.h:13
bool exec
Definition: comm.h:15
const char * comm__str(const struct comm *comm)
Definition: comm.c:143
static struct comm_str * __comm_str__findnew(const char *str, struct rb_root *root)
Definition: comm.c:59
#define new
Definition: util-cxx.h:20
int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
Definition: comm.c:120
refcount_t refcnt
Definition: comm.c:14
#define zfree(ptr)
Definition: util.h:25
void comm__free(struct comm *comm)
Definition: comm.c:137
Definition: comm.c:11
static struct rb_root comm_str_root
Definition: comm.c:18
void free(void *)
int down_write(struct rw_semaphore *sem)
Definition: rwsem.c:24
static struct comm_str * comm_str__alloc(const char *str)
Definition: comm.c:39
void static void * zalloc(size_t size)
Definition: util.h:20
struct comm_str * comm_str
Definition: comm.h:12