]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/perf/util/values.c
Merge branch 'tsc2007' into next
[karo-tx-linux.git] / tools / perf / util / values.c
1 #include <stdlib.h>
2
3 #include "util.h"
4 #include "values.h"
5 #include "debug.h"
6
7 int perf_read_values_init(struct perf_read_values *values)
8 {
9         values->threads_max = 16;
10         values->pid = malloc(values->threads_max * sizeof(*values->pid));
11         values->tid = malloc(values->threads_max * sizeof(*values->tid));
12         values->value = malloc(values->threads_max * sizeof(*values->value));
13         if (!values->pid || !values->tid || !values->value) {
14                 pr_debug("failed to allocate read_values threads arrays");
15                 goto out_free_pid;
16         }
17         values->threads = 0;
18
19         values->counters_max = 16;
20         values->counterrawid = malloc(values->counters_max
21                                       * sizeof(*values->counterrawid));
22         values->countername = malloc(values->counters_max
23                                      * sizeof(*values->countername));
24         if (!values->counterrawid || !values->countername) {
25                 pr_debug("failed to allocate read_values counters arrays");
26                 goto out_free_counter;
27         }
28         values->counters = 0;
29
30         return 0;
31
32 out_free_counter:
33         zfree(&values->counterrawid);
34         zfree(&values->countername);
35 out_free_pid:
36         zfree(&values->pid);
37         zfree(&values->tid);
38         zfree(&values->value);
39         return -ENOMEM;
40 }
41
42 void perf_read_values_destroy(struct perf_read_values *values)
43 {
44         int i;
45
46         if (!values->threads_max || !values->counters_max)
47                 return;
48
49         for (i = 0; i < values->threads; i++)
50                 zfree(&values->value[i]);
51         zfree(&values->value);
52         zfree(&values->pid);
53         zfree(&values->tid);
54         zfree(&values->counterrawid);
55         for (i = 0; i < values->counters; i++)
56                 zfree(&values->countername[i]);
57         zfree(&values->countername);
58 }
59
60 static int perf_read_values__enlarge_threads(struct perf_read_values *values)
61 {
62         int nthreads_max = values->threads_max * 2;
63         void *npid = realloc(values->pid, nthreads_max * sizeof(*values->pid)),
64              *ntid = realloc(values->tid, nthreads_max * sizeof(*values->tid)),
65              *nvalue = realloc(values->value, nthreads_max * sizeof(*values->value));
66
67         if (!npid || !ntid || !nvalue)
68                 goto out_err;
69
70         values->threads_max = nthreads_max;
71         values->pid = npid;
72         values->tid = ntid;
73         values->value = nvalue;
74         return 0;
75 out_err:
76         free(npid);
77         free(ntid);
78         free(nvalue);
79         pr_debug("failed to enlarge read_values threads arrays");
80         return -ENOMEM;
81 }
82
83 static int perf_read_values__findnew_thread(struct perf_read_values *values,
84                                             u32 pid, u32 tid)
85 {
86         int i;
87
88         for (i = 0; i < values->threads; i++)
89                 if (values->pid[i] == pid && values->tid[i] == tid)
90                         return i;
91
92         if (values->threads == values->threads_max) {
93                 i = perf_read_values__enlarge_threads(values);
94                 if (i < 0)
95                         return i;
96         }
97
98         i = values->threads + 1;
99         values->value[i] = malloc(values->counters_max * sizeof(**values->value));
100         if (!values->value[i]) {
101                 pr_debug("failed to allocate read_values counters array");
102                 return -ENOMEM;
103         }
104         values->pid[i] = pid;
105         values->tid[i] = tid;
106         values->threads = i;
107
108         return i;
109 }
110
111 static void perf_read_values__enlarge_counters(struct perf_read_values *values)
112 {
113         int i;
114
115         values->counters_max *= 2;
116         values->counterrawid = realloc(values->counterrawid,
117                                        values->counters_max * sizeof(*values->counterrawid));
118         values->countername = realloc(values->countername,
119                                       values->counters_max * sizeof(*values->countername));
120         if (!values->counterrawid || !values->countername)
121                 die("failed to enlarge read_values counters arrays");
122
123         for (i = 0; i < values->threads; i++) {
124                 values->value[i] = realloc(values->value[i],
125                                            values->counters_max * sizeof(**values->value));
126                 if (!values->value[i])
127                         die("failed to enlarge read_values counters arrays");
128         }
129 }
130
131 static int perf_read_values__findnew_counter(struct perf_read_values *values,
132                                              u64 rawid, const char *name)
133 {
134         int i;
135
136         for (i = 0; i < values->counters; i++)
137                 if (values->counterrawid[i] == rawid)
138                         return i;
139
140         if (values->counters == values->counters_max)
141                 perf_read_values__enlarge_counters(values);
142
143         i = values->counters++;
144         values->counterrawid[i] = rawid;
145         values->countername[i] = strdup(name);
146
147         return i;
148 }
149
150 int perf_read_values_add_value(struct perf_read_values *values,
151                                 u32 pid, u32 tid,
152                                 u64 rawid, const char *name, u64 value)
153 {
154         int tindex, cindex;
155
156         tindex = perf_read_values__findnew_thread(values, pid, tid);
157         if (tindex < 0)
158                 return tindex;
159         cindex = perf_read_values__findnew_counter(values, rawid, name);
160         if (cindex < 0)
161                 return cindex;
162
163         values->value[tindex][cindex] = value;
164         return 0;
165 }
166
167 static void perf_read_values__display_pretty(FILE *fp,
168                                              struct perf_read_values *values)
169 {
170         int i, j;
171         int pidwidth, tidwidth;
172         int *counterwidth;
173
174         counterwidth = malloc(values->counters * sizeof(*counterwidth));
175         if (!counterwidth)
176                 die("failed to allocate counterwidth array");
177         tidwidth = 3;
178         pidwidth = 3;
179         for (j = 0; j < values->counters; j++)
180                 counterwidth[j] = strlen(values->countername[j]);
181         for (i = 0; i < values->threads; i++) {
182                 int width;
183
184                 width = snprintf(NULL, 0, "%d", values->pid[i]);
185                 if (width > pidwidth)
186                         pidwidth = width;
187                 width = snprintf(NULL, 0, "%d", values->tid[i]);
188                 if (width > tidwidth)
189                         tidwidth = width;
190                 for (j = 0; j < values->counters; j++) {
191                         width = snprintf(NULL, 0, "%" PRIu64, values->value[i][j]);
192                         if (width > counterwidth[j])
193                                 counterwidth[j] = width;
194                 }
195         }
196
197         fprintf(fp, "# %*s  %*s", pidwidth, "PID", tidwidth, "TID");
198         for (j = 0; j < values->counters; j++)
199                 fprintf(fp, "  %*s", counterwidth[j], values->countername[j]);
200         fprintf(fp, "\n");
201
202         for (i = 0; i < values->threads; i++) {
203                 fprintf(fp, "  %*d  %*d", pidwidth, values->pid[i],
204                         tidwidth, values->tid[i]);
205                 for (j = 0; j < values->counters; j++)
206                         fprintf(fp, "  %*" PRIu64,
207                                 counterwidth[j], values->value[i][j]);
208                 fprintf(fp, "\n");
209         }
210         free(counterwidth);
211 }
212
213 static void perf_read_values__display_raw(FILE *fp,
214                                           struct perf_read_values *values)
215 {
216         int width, pidwidth, tidwidth, namewidth, rawwidth, countwidth;
217         int i, j;
218
219         tidwidth = 3; /* TID */
220         pidwidth = 3; /* PID */
221         namewidth = 4; /* "Name" */
222         rawwidth = 3; /* "Raw" */
223         countwidth = 5; /* "Count" */
224
225         for (i = 0; i < values->threads; i++) {
226                 width = snprintf(NULL, 0, "%d", values->pid[i]);
227                 if (width > pidwidth)
228                         pidwidth = width;
229                 width = snprintf(NULL, 0, "%d", values->tid[i]);
230                 if (width > tidwidth)
231                         tidwidth = width;
232         }
233         for (j = 0; j < values->counters; j++) {
234                 width = strlen(values->countername[j]);
235                 if (width > namewidth)
236                         namewidth = width;
237                 width = snprintf(NULL, 0, "%" PRIx64, values->counterrawid[j]);
238                 if (width > rawwidth)
239                         rawwidth = width;
240         }
241         for (i = 0; i < values->threads; i++) {
242                 for (j = 0; j < values->counters; j++) {
243                         width = snprintf(NULL, 0, "%" PRIu64, values->value[i][j]);
244                         if (width > countwidth)
245                                 countwidth = width;
246                 }
247         }
248
249         fprintf(fp, "# %*s  %*s  %*s  %*s  %*s\n",
250                 pidwidth, "PID", tidwidth, "TID",
251                 namewidth, "Name", rawwidth, "Raw",
252                 countwidth, "Count");
253         for (i = 0; i < values->threads; i++)
254                 for (j = 0; j < values->counters; j++)
255                         fprintf(fp, "  %*d  %*d  %*s  %*" PRIx64 "  %*" PRIu64,
256                                 pidwidth, values->pid[i],
257                                 tidwidth, values->tid[i],
258                                 namewidth, values->countername[j],
259                                 rawwidth, values->counterrawid[j],
260                                 countwidth, values->value[i][j]);
261 }
262
263 void perf_read_values_display(FILE *fp, struct perf_read_values *values, int raw)
264 {
265         if (raw)
266                 perf_read_values__display_raw(fp, values);
267         else
268                 perf_read_values__display_pretty(fp, values);
269 }