10 int perf_read_values_init(struct perf_read_values
*values
)
12 values
->threads_max
= 16;
13 values
->pid
= malloc(values
->threads_max
* sizeof(*values
->pid
));
14 values
->tid
= malloc(values
->threads_max
* sizeof(*values
->tid
));
15 values
->value
= malloc(values
->threads_max
* sizeof(*values
->value
));
16 if (!values
->pid
|| !values
->tid
|| !values
->value
) {
17 pr_debug("failed to allocate read_values threads arrays");
22 values
->counters_max
= 16;
23 values
->counterrawid
= malloc(values
->counters_max
24 * sizeof(*values
->counterrawid
));
25 values
->countername
= malloc(values
->counters_max
26 * sizeof(*values
->countername
));
27 if (!values
->counterrawid
|| !values
->countername
) {
28 pr_debug("failed to allocate read_values counters arrays");
29 goto out_free_counter
;
36 zfree(&values
->counterrawid
);
37 zfree(&values
->countername
);
41 zfree(&values
->value
);
45 void perf_read_values_destroy(struct perf_read_values
*values
)
49 if (!values
->threads_max
|| !values
->counters_max
)
52 for (i
= 0; i
< values
->threads
; i
++)
53 zfree(&values
->value
[i
]);
54 zfree(&values
->value
);
57 zfree(&values
->counterrawid
);
58 for (i
= 0; i
< values
->counters
; i
++)
59 zfree(&values
->countername
[i
]);
60 zfree(&values
->countername
);
63 static int perf_read_values__enlarge_threads(struct perf_read_values
*values
)
65 int nthreads_max
= values
->threads_max
* 2;
66 void *npid
= realloc(values
->pid
, nthreads_max
* sizeof(*values
->pid
)),
67 *ntid
= realloc(values
->tid
, nthreads_max
* sizeof(*values
->tid
)),
68 *nvalue
= realloc(values
->value
, nthreads_max
* sizeof(*values
->value
));
70 if (!npid
|| !ntid
|| !nvalue
)
73 values
->threads_max
= nthreads_max
;
76 values
->value
= nvalue
;
82 pr_debug("failed to enlarge read_values threads arrays");
86 static int perf_read_values__findnew_thread(struct perf_read_values
*values
,
91 for (i
= 0; i
< values
->threads
; i
++)
92 if (values
->pid
[i
] == pid
&& values
->tid
[i
] == tid
)
95 if (values
->threads
== values
->threads_max
) {
96 i
= perf_read_values__enlarge_threads(values
);
101 i
= values
->threads
+ 1;
102 values
->value
[i
] = malloc(values
->counters_max
* sizeof(**values
->value
));
103 if (!values
->value
[i
]) {
104 pr_debug("failed to allocate read_values counters array");
107 values
->pid
[i
] = pid
;
108 values
->tid
[i
] = tid
;
114 static int perf_read_values__enlarge_counters(struct perf_read_values
*values
)
117 int i
, counters_max
= values
->counters_max
* 2;
118 u64
*counterrawid
= realloc(values
->counterrawid
, counters_max
* sizeof(*values
->counterrawid
));
121 pr_debug("failed to enlarge read_values rawid array");
125 countername
= realloc(values
->countername
, counters_max
* sizeof(*values
->countername
));
127 pr_debug("failed to enlarge read_values rawid array");
131 for (i
= 0; i
< values
->threads
; i
++) {
132 u64
*value
= realloc(values
->value
[i
], counters_max
* sizeof(**values
->value
));
135 pr_debug("failed to enlarge read_values ->values array");
139 values
->value
[i
] = value
;
142 values
->counters_max
= counters_max
;
143 values
->counterrawid
= counterrawid
;
144 values
->countername
= countername
;
155 static int perf_read_values__findnew_counter(struct perf_read_values
*values
,
156 u64 rawid
, const char *name
)
160 for (i
= 0; i
< values
->counters
; i
++)
161 if (values
->counterrawid
[i
] == rawid
)
164 if (values
->counters
== values
->counters_max
) {
165 i
= perf_read_values__enlarge_counters(values
);
170 i
= values
->counters
++;
171 values
->counterrawid
[i
] = rawid
;
172 values
->countername
[i
] = strdup(name
);
177 int perf_read_values_add_value(struct perf_read_values
*values
,
179 u64 rawid
, const char *name
, u64 value
)
183 tindex
= perf_read_values__findnew_thread(values
, pid
, tid
);
186 cindex
= perf_read_values__findnew_counter(values
, rawid
, name
);
190 values
->value
[tindex
][cindex
] = value
;
194 static void perf_read_values__display_pretty(FILE *fp
,
195 struct perf_read_values
*values
)
198 int pidwidth
, tidwidth
;
201 counterwidth
= malloc(values
->counters
* sizeof(*counterwidth
));
203 fprintf(fp
, "INTERNAL ERROR: Failed to allocate counterwidth array\n");
208 for (j
= 0; j
< values
->counters
; j
++)
209 counterwidth
[j
] = strlen(values
->countername
[j
]);
210 for (i
= 0; i
< values
->threads
; i
++) {
213 width
= snprintf(NULL
, 0, "%d", values
->pid
[i
]);
214 if (width
> pidwidth
)
216 width
= snprintf(NULL
, 0, "%d", values
->tid
[i
]);
217 if (width
> tidwidth
)
219 for (j
= 0; j
< values
->counters
; j
++) {
220 width
= snprintf(NULL
, 0, "%" PRIu64
, values
->value
[i
][j
]);
221 if (width
> counterwidth
[j
])
222 counterwidth
[j
] = width
;
226 fprintf(fp
, "# %*s %*s", pidwidth
, "PID", tidwidth
, "TID");
227 for (j
= 0; j
< values
->counters
; j
++)
228 fprintf(fp
, " %*s", counterwidth
[j
], values
->countername
[j
]);
231 for (i
= 0; i
< values
->threads
; i
++) {
232 fprintf(fp
, " %*d %*d", pidwidth
, values
->pid
[i
],
233 tidwidth
, values
->tid
[i
]);
234 for (j
= 0; j
< values
->counters
; j
++)
235 fprintf(fp
, " %*" PRIu64
,
236 counterwidth
[j
], values
->value
[i
][j
]);
242 static void perf_read_values__display_raw(FILE *fp
,
243 struct perf_read_values
*values
)
245 int width
, pidwidth
, tidwidth
, namewidth
, rawwidth
, countwidth
;
248 tidwidth
= 3; /* TID */
249 pidwidth
= 3; /* PID */
250 namewidth
= 4; /* "Name" */
251 rawwidth
= 3; /* "Raw" */
252 countwidth
= 5; /* "Count" */
254 for (i
= 0; i
< values
->threads
; i
++) {
255 width
= snprintf(NULL
, 0, "%d", values
->pid
[i
]);
256 if (width
> pidwidth
)
258 width
= snprintf(NULL
, 0, "%d", values
->tid
[i
]);
259 if (width
> tidwidth
)
262 for (j
= 0; j
< values
->counters
; j
++) {
263 width
= strlen(values
->countername
[j
]);
264 if (width
> namewidth
)
266 width
= snprintf(NULL
, 0, "%" PRIx64
, values
->counterrawid
[j
]);
267 if (width
> rawwidth
)
270 for (i
= 0; i
< values
->threads
; i
++) {
271 for (j
= 0; j
< values
->counters
; j
++) {
272 width
= snprintf(NULL
, 0, "%" PRIu64
, values
->value
[i
][j
]);
273 if (width
> countwidth
)
278 fprintf(fp
, "# %*s %*s %*s %*s %*s\n",
279 pidwidth
, "PID", tidwidth
, "TID",
280 namewidth
, "Name", rawwidth
, "Raw",
281 countwidth
, "Count");
282 for (i
= 0; i
< values
->threads
; i
++)
283 for (j
= 0; j
< values
->counters
; j
++)
284 fprintf(fp
, " %*d %*d %*s %*" PRIx64
" %*" PRIu64
,
285 pidwidth
, values
->pid
[i
],
286 tidwidth
, values
->tid
[i
],
287 namewidth
, values
->countername
[j
],
288 rawwidth
, values
->counterrawid
[j
],
289 countwidth
, values
->value
[i
][j
]);
292 void perf_read_values_display(FILE *fp
, struct perf_read_values
*values
, int raw
)
295 perf_read_values__display_raw(fp
, values
);
297 perf_read_values__display_pretty(fp
, values
);