Blame view

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