@@ -119,6 +119,37 @@ static struct timerlat_top_data *timerlat_alloc_top(int nr_cpus)
119
119
return NULL ;
120
120
}
121
121
122
+ static void
123
+ timerlat_top_reset_sum (struct timerlat_top_cpu * summary )
124
+ {
125
+ memset (summary , 0 , sizeof (* summary ));
126
+ summary -> min_irq = ~0 ;
127
+ summary -> min_thread = ~0 ;
128
+ summary -> min_user = ~0 ;
129
+ }
130
+
131
+ static void
132
+ timerlat_top_update_sum (struct osnoise_tool * tool , int cpu , struct timerlat_top_cpu * sum )
133
+ {
134
+ struct timerlat_top_data * data = tool -> data ;
135
+ struct timerlat_top_cpu * cpu_data = & data -> cpu_data [cpu ];
136
+
137
+ sum -> irq_count += cpu_data -> irq_count ;
138
+ update_min (& sum -> min_irq , & cpu_data -> min_irq );
139
+ update_sum (& sum -> sum_irq , & cpu_data -> sum_irq );
140
+ update_max (& sum -> max_irq , & cpu_data -> max_irq );
141
+
142
+ sum -> thread_count += cpu_data -> thread_count ;
143
+ update_min (& sum -> min_thread , & cpu_data -> min_thread );
144
+ update_sum (& sum -> sum_thread , & cpu_data -> sum_thread );
145
+ update_max (& sum -> max_thread , & cpu_data -> max_thread );
146
+
147
+ sum -> user_count += cpu_data -> user_count ;
148
+ update_min (& sum -> min_user , & cpu_data -> min_user );
149
+ update_sum (& sum -> sum_user , & cpu_data -> sum_user );
150
+ update_max (& sum -> max_user , & cpu_data -> max_user );
151
+ }
152
+
122
153
/*
123
154
* timerlat_hist_update - record a new timerlat occurent on cpu, updating data
124
155
*/
@@ -285,6 +316,77 @@ static void timerlat_top_print(struct osnoise_tool *top, int cpu)
285
316
}
286
317
}
287
318
319
+ /*
320
+ * timerlat_top_print_sum - prints the summary output
321
+ */
322
+ static void
323
+ timerlat_top_print_sum (struct osnoise_tool * top , struct timerlat_top_cpu * summary )
324
+ {
325
+ const char * split = "----------------------------------------" ;
326
+ struct timerlat_top_params * params = top -> params ;
327
+ unsigned long long count = summary -> irq_count ;
328
+ int divisor = params -> output_divisor ;
329
+ struct trace_seq * s = top -> trace .seq ;
330
+ int e = 0 ;
331
+
332
+ if (divisor == 0 )
333
+ return ;
334
+
335
+ /*
336
+ * Skip if no data is available: is this cpu offline?
337
+ */
338
+ if (!summary -> irq_count && !summary -> thread_count )
339
+ return ;
340
+
341
+ while (count > 999999 ) {
342
+ e ++ ;
343
+ count /= 10 ;
344
+ }
345
+
346
+ trace_seq_printf (s , "%.*s|%.*s|%.*s" , 15 , split , 40 , split , 39 , split );
347
+ if (params -> user_top )
348
+ trace_seq_printf (s , "-|%.*s" , 39 , split );
349
+ trace_seq_printf (s , "\n" );
350
+
351
+ trace_seq_printf (s , "ALL #%-6llu e%d |" , count , e );
352
+
353
+ if (!summary -> irq_count ) {
354
+ trace_seq_printf (s , " %s %s %s |" , no_value , no_value , no_value );
355
+ } else {
356
+ trace_seq_printf (s , " " );
357
+ trace_seq_printf (s , "%9llu " , summary -> min_irq / params -> output_divisor );
358
+ trace_seq_printf (s , "%9llu " , (summary -> sum_irq / summary -> irq_count ) / divisor );
359
+ trace_seq_printf (s , "%9llu |" , summary -> max_irq / divisor );
360
+ }
361
+
362
+ if (!summary -> thread_count ) {
363
+ trace_seq_printf (s , "%s %s %s %s" , no_value , no_value , no_value , no_value );
364
+ } else {
365
+ trace_seq_printf (s , " " );
366
+ trace_seq_printf (s , "%9llu " , summary -> min_thread / divisor );
367
+ trace_seq_printf (s , "%9llu " ,
368
+ (summary -> sum_thread / summary -> thread_count ) / divisor );
369
+ trace_seq_printf (s , "%9llu" , summary -> max_thread / divisor );
370
+ }
371
+
372
+ if (!params -> user_top ) {
373
+ trace_seq_printf (s , "\n" );
374
+ return ;
375
+ }
376
+
377
+ trace_seq_printf (s , " |" );
378
+
379
+ if (!summary -> user_count ) {
380
+ trace_seq_printf (s , " %s %s %s |" , no_value , no_value , no_value );
381
+ } else {
382
+ trace_seq_printf (s , " " );
383
+ trace_seq_printf (s , "%9llu " , summary -> min_user / divisor );
384
+ trace_seq_printf (s , "%9llu " ,
385
+ (summary -> sum_user / summary -> user_count ) / divisor );
386
+ trace_seq_printf (s , "%9llu\n" , summary -> max_user / divisor );
387
+ }
388
+ }
389
+
288
390
/*
289
391
* clear_terminal - clears the output terminal
290
392
*/
@@ -301,6 +403,7 @@ static void
301
403
timerlat_print_stats (struct timerlat_top_params * params , struct osnoise_tool * top )
302
404
{
303
405
struct trace_instance * trace = & top -> trace ;
406
+ struct timerlat_top_cpu summary ;
304
407
static int nr_cpus = -1 ;
305
408
int i ;
306
409
@@ -313,14 +416,19 @@ timerlat_print_stats(struct timerlat_top_params *params, struct osnoise_tool *to
313
416
if (!params -> quiet )
314
417
clear_terminal (trace -> seq );
315
418
419
+ timerlat_top_reset_sum (& summary );
420
+
316
421
timerlat_top_header (params , top );
317
422
318
423
for (i = 0 ; i < nr_cpus ; i ++ ) {
319
424
if (params -> cpus && !CPU_ISSET (i , & params -> monitored_cpus ))
320
425
continue ;
321
426
timerlat_top_print (top , i );
427
+ timerlat_top_update_sum (top , i , & summary );
322
428
}
323
429
430
+ timerlat_top_print_sum (top , & summary );
431
+
324
432
trace_seq_do_printf (trace -> seq );
325
433
trace_seq_reset (trace -> seq );
326
434
}
0 commit comments