1 // SPDX-License-Identifier: GPL-2.0
11 int perf_read_values_init(struct perf_read_values
*values
)
13 values
->threads_max
= 16;
14 values
->pid
= malloc(values
->threads_max
* sizeof(*values
->pid
));
15 values
->tid
= malloc(values
->threads_max
* sizeof(*values
->tid
));
16 values
->value
= zalloc(values
->threads_max
* sizeof(*values
->value
));
17 if (!values
->pid
|| !values
->tid
|| !values
->value
) {
18 pr_debug("failed to allocate read_values threads arrays");
23 values
->counters_max
= 16;
24 values
->counterrawid
= malloc(values
->counters_max
25 * sizeof(*values
->counterrawid
));
26 values
->countername
= malloc(values
->counters_max
27 * sizeof(*values
->countername
));
28 if (!values
->counterrawid
|| !values
->countername
) {
29 pr_debug("failed to allocate read_values counters arrays");
30 goto out_free_counter
;
37 zfree(&values
->counterrawid
);
38 zfree(&values
->countername
);
42 zfree(&values
->value
);
46 void perf_read_values_destroy(struct perf_read_values
*values
)
50 if (!values
->threads_max
|| !values
->counters_max
)
53 for (i
= 0; i
< values
->threads
; i
++)
54 zfree(&values
->value
[i
]);
55 zfree(&values
->value
);
58 zfree(&values
->counterrawid
);
59 for (i
= 0; i
< values
->counters
; i
++)
60 zfree(&values
->countername
[i
]);
61 zfree(&values
->countername
);
64 static int perf_read_values__enlarge_threads(struct perf_read_values
*values
)
66 int nthreads_max
= values
->threads_max
* 2;
67 void *npid
= realloc(values
->pid
, nthreads_max
* sizeof(*values
->pid
)),
68 *ntid
= realloc(values
->tid
, nthreads_max
* sizeof(*values
->tid
)),
69 *nvalue
= realloc(values
->value
, nthreads_max
* sizeof(*values
->value
));
71 if (!npid
|| !ntid
|| !nvalue
)
74 values
->threads_max
= nthreads_max
;
77 values
->value
= nvalue
;
83 pr_debug("failed to enlarge read_values threads arrays");
87 static int perf_read_values__findnew_thread(struct perf_read_values
*values
,
92 for (i
= 0; i
< values
->threads
; i
++)
93 if (values
->pid
[i
] == pid
&& values
->tid
[i
] == tid
)
96 if (values
->threads
== values
->threads_max
) {
97 i
= perf_read_values__enlarge_threads(values
);
104 values
->value
[i
] = zalloc(values
->counters_max
* sizeof(**values
->value
));
105 if (!values
->value
[i
]) {
106 pr_debug("failed to allocate read_values counters array");
109 values
->pid
[i
] = pid
;
110 values
->tid
[i
] = tid
;
111 values
->threads
= i
+ 1;
116 static int perf_read_values__enlarge_counters(struct perf_read_values
*values
)
119 int i
, counters_max
= values
->counters_max
* 2;
120 u64
*counterrawid
= realloc(values
->counterrawid
, counters_max
* sizeof(*values
->counterrawid
));
123 pr_debug("failed to enlarge read_values rawid array");
127 countername
= realloc(values
->countername
, counters_max
* sizeof(*values
->countername
));
129 pr_debug("failed to enlarge read_values rawid array");
133 for (i
= 0; i
< values
->threads
; i
++) {
134 u64
*value
= realloc(values
->value
[i
], counters_max
* sizeof(**values
->value
));
138 pr_debug("failed to enlarge read_values ->values array");
142 for (j
= values
->counters_max
; j
< counters_max
; j
++)
145 values
->value
[i
] = value
;
148 values
->counters_max
= counters_max
;
149 values
->counterrawid
= counterrawid
;
150 values
->countername
= countername
;
161 static int perf_read_values__findnew_counter(struct perf_read_values
*values
,
162 u64 rawid
, const char *name
)
166 for (i
= 0; i
< values
->counters
; i
++)
167 if (values
->counterrawid
[i
] == rawid
)
170 if (values
->counters
== values
->counters_max
) {
171 i
= perf_read_values__enlarge_counters(values
);
176 i
= values
->counters
++;
177 values
->counterrawid
[i
] = rawid
;
178 values
->countername
[i
] = strdup(name
);
183 int perf_read_values_add_value(struct perf_read_values
*values
,
185 u64 rawid
, const char *name
, u64 value
)
189 tindex
= perf_read_values__findnew_thread(values
, pid
, tid
);
192 cindex
= perf_read_values__findnew_counter(values
, rawid
, name
);
196 values
->value
[tindex
][cindex
] += value
;
200 static void perf_read_values__display_pretty(FILE *fp
,
201 struct perf_read_values
*values
)
204 int pidwidth
, tidwidth
;
207 counterwidth
= malloc(values
->counters
* sizeof(*counterwidth
));
209 fprintf(fp
, "INTERNAL ERROR: Failed to allocate counterwidth array\n");
214 for (j
= 0; j
< values
->counters
; j
++)
215 counterwidth
[j
] = strlen(values
->countername
[j
]);
216 for (i
= 0; i
< values
->threads
; i
++) {
219 width
= snprintf(NULL
, 0, "%d", values
->pid
[i
]);
220 if (width
> pidwidth
)
222 width
= snprintf(NULL
, 0, "%d", values
->tid
[i
]);
223 if (width
> tidwidth
)
225 for (j
= 0; j
< values
->counters
; j
++) {
226 width
= snprintf(NULL
, 0, "%" PRIu64
, values
->value
[i
][j
]);
227 if (width
> counterwidth
[j
])
228 counterwidth
[j
] = width
;
232 fprintf(fp
, "# %*s %*s", pidwidth
, "PID", tidwidth
, "TID");
233 for (j
= 0; j
< values
->counters
; j
++)
234 fprintf(fp
, " %*s", counterwidth
[j
], values
->countername
[j
]);
237 for (i
= 0; i
< values
->threads
; i
++) {
238 fprintf(fp
, " %*d %*d", pidwidth
, values
->pid
[i
],
239 tidwidth
, values
->tid
[i
]);
240 for (j
= 0; j
< values
->counters
; j
++)
241 fprintf(fp
, " %*" PRIu64
,
242 counterwidth
[j
], values
->value
[i
][j
]);
248 static void perf_read_values__display_raw(FILE *fp
,
249 struct perf_read_values
*values
)
251 int width
, pidwidth
, tidwidth
, namewidth
, rawwidth
, countwidth
;
254 tidwidth
= 3; /* TID */
255 pidwidth
= 3; /* PID */
256 namewidth
= 4; /* "Name" */
257 rawwidth
= 3; /* "Raw" */
258 countwidth
= 5; /* "Count" */
260 for (i
= 0; i
< values
->threads
; i
++) {
261 width
= snprintf(NULL
, 0, "%d", values
->pid
[i
]);
262 if (width
> pidwidth
)
264 width
= snprintf(NULL
, 0, "%d", values
->tid
[i
]);
265 if (width
> tidwidth
)
268 for (j
= 0; j
< values
->counters
; j
++) {
269 width
= strlen(values
->countername
[j
]);
270 if (width
> namewidth
)
272 width
= snprintf(NULL
, 0, "%" PRIx64
, values
->counterrawid
[j
]);
273 if (width
> rawwidth
)
276 for (i
= 0; i
< values
->threads
; i
++) {
277 for (j
= 0; j
< values
->counters
; j
++) {
278 width
= snprintf(NULL
, 0, "%" PRIu64
, values
->value
[i
][j
]);
279 if (width
> countwidth
)
284 fprintf(fp
, "# %*s %*s %*s %*s %*s\n",
285 pidwidth
, "PID", tidwidth
, "TID",
286 namewidth
, "Name", rawwidth
, "Raw",
287 countwidth
, "Count");
288 for (i
= 0; i
< values
->threads
; i
++)
289 for (j
= 0; j
< values
->counters
; j
++)
290 fprintf(fp
, " %*d %*d %*s %*" PRIx64
" %*" PRIu64
,
291 pidwidth
, values
->pid
[i
],
292 tidwidth
, values
->tid
[i
],
293 namewidth
, values
->countername
[j
],
294 rawwidth
, values
->counterrawid
[j
],
295 countwidth
, values
->value
[i
][j
]);
298 void perf_read_values_display(FILE *fp
, struct perf_read_values
*values
, int raw
)
301 perf_read_values__display_raw(fp
, values
);
303 perf_read_values__display_pretty(fp
, values
);