~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/stat-display.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/perf/util/stat-display.c (Version linux-6.12-rc7) and /tools/perf/util/stat-display.c (Version linux-4.4.302)


  1 #include <stdlib.h>                                 1 
  2 #include <stdio.h>                                
  3 #include <inttypes.h>                             
  4 #include <linux/string.h>                         
  5 #include <linux/time64.h>                         
  6 #include <math.h>                                 
  7 #include <perf/cpumap.h>                          
  8 #include "color.h"                                
  9 #include "counts.h"                               
 10 #include "evlist.h"                               
 11 #include "evsel.h"                                
 12 #include "stat.h"                                 
 13 #include "top.h"                                  
 14 #include "thread_map.h"                           
 15 #include "cpumap.h"                               
 16 #include "string2.h"                              
 17 #include <linux/ctype.h>                          
 18 #include "cgroup.h"                               
 19 #include <api/fs/fs.h>                            
 20 #include "util.h"                                 
 21 #include "iostat.h"                               
 22 #include "pmu.h"                                  
 23 #include "pmus.h"                                 
 24                                                   
 25 #define CNTR_NOT_SUPPORTED      "<not supporte    
 26 #define CNTR_NOT_COUNTED        "<not counted>    
 27                                                   
 28 #define MGROUP_LEN   50                           
 29 #define METRIC_LEN   38                           
 30 #define EVNAME_LEN   32                           
 31 #define COUNTS_LEN   18                           
 32 #define INTERVAL_LEN 16                           
 33 #define CGROUP_LEN   16                           
 34 #define COMM_LEN     16                           
 35 #define PID_LEN       7                           
 36 #define CPUS_LEN      4                           
 37                                                   
 38 static int aggr_header_lens[] = {                 
 39         [AGGR_CORE]     = 18,                     
 40         [AGGR_CACHE]    = 22,                     
 41         [AGGR_CLUSTER]  = 20,                     
 42         [AGGR_DIE]      = 12,                     
 43         [AGGR_SOCKET]   = 6,                      
 44         [AGGR_NODE]     = 6,                      
 45         [AGGR_NONE]     = 6,                      
 46         [AGGR_THREAD]   = 16,                     
 47         [AGGR_GLOBAL]   = 0,                      
 48 };                                                
 49                                                   
 50 static const char *aggr_header_csv[] = {          
 51         [AGGR_CORE]     =       "core,cpus,",     
 52         [AGGR_CACHE]    =       "cache,cpus,",    
 53         [AGGR_CLUSTER]  =       "cluster,cpus,    
 54         [AGGR_DIE]      =       "die,cpus,",      
 55         [AGGR_SOCKET]   =       "socket,cpus,"    
 56         [AGGR_NONE]     =       "cpu,",           
 57         [AGGR_THREAD]   =       "comm-pid,",      
 58         [AGGR_NODE]     =       "node,",          
 59         [AGGR_GLOBAL]   =       ""                
 60 };                                                
 61                                                   
 62 static const char *aggr_header_std[] = {          
 63         [AGGR_CORE]     =       "core",           
 64         [AGGR_CACHE]    =       "cache",          
 65         [AGGR_CLUSTER]  =       "cluster",        
 66         [AGGR_DIE]      =       "die",            
 67         [AGGR_SOCKET]   =       "socket",         
 68         [AGGR_NONE]     =       "cpu",            
 69         [AGGR_THREAD]   =       "comm-pid",       
 70         [AGGR_NODE]     =       "node",           
 71         [AGGR_GLOBAL]   =       ""                
 72 };                                                
 73                                                   
 74 static void print_running_std(struct perf_stat    
 75 {                                                 
 76         if (run != ena)                           
 77                 fprintf(config->output, "  (%.    
 78 }                                                 
 79                                                   
 80 static void print_running_csv(struct perf_stat    
 81 {                                                 
 82         double enabled_percent = 100;             
 83                                                   
 84         if (run != ena)                           
 85                 enabled_percent = 100 * run /     
 86         fprintf(config->output, "%s%" PRIu64 "    
 87                 config->csv_sep, run, config->    
 88 }                                                 
 89                                                   
 90 static void print_running_json(struct perf_sta    
 91 {                                                 
 92         double enabled_percent = 100;             
 93                                                   
 94         if (run != ena)                           
 95                 enabled_percent = 100 * run /     
 96         fprintf(config->output, "\"event-runti    
 97                 run, enabled_percent);            
 98 }                                                 
 99                                                   
100 static void print_running(struct perf_stat_con    
101                           u64 run, u64 ena, bo    
102 {                                                 
103         if (config->json_output) {                
104                 if (before_metric)                
105                         print_running_json(con    
106         } else if (config->csv_output) {          
107                 if (before_metric)                
108                         print_running_csv(conf    
109         } else {                                  
110                 if (!before_metric)               
111                         print_running_std(conf    
112         }                                         
113 }                                                 
114                                                   
115 static void print_noise_pct_std(struct perf_st    
116                                 double pct)       
117 {                                                 
118         if (pct)                                  
119                 fprintf(config->output, "  ( +    
120 }                                                 
121                                                   
122 static void print_noise_pct_csv(struct perf_st    
123                                 double pct)       
124 {                                                 
125         fprintf(config->output, "%s%.2f%%", co    
126 }                                                 
127                                                   
128 static void print_noise_pct_json(struct perf_s    
129                                  double pct)      
130 {                                                 
131         fprintf(config->output, "\"variance\"     
132 }                                                 
133                                                   
134 static void print_noise_pct(struct perf_stat_c    
135                             double total, doub    
136 {                                                 
137         double pct = rel_stddev_stats(total, a    
138                                                   
139         if (config->json_output) {                
140                 if (before_metric)                
141                         print_noise_pct_json(c    
142         } else if (config->csv_output) {          
143                 if (before_metric)                
144                         print_noise_pct_csv(co    
145         } else {                                  
146                 if (!before_metric)               
147                         print_noise_pct_std(co    
148         }                                         
149 }                                                 
150                                                   
151 static void print_noise(struct perf_stat_confi    
152                         struct evsel *evsel, d    
153 {                                                 
154         struct perf_stat_evsel *ps;               
155                                                   
156         if (config->run_count == 1)               
157                 return;                           
158                                                   
159         ps = evsel->stats;                        
160         print_noise_pct(config, stddev_stats(&    
161 }                                                 
162                                                   
163 static void print_cgroup_std(struct perf_stat_    
164 {                                                 
165         fprintf(config->output, " %-*s", CGROU    
166 }                                                 
167                                                   
168 static void print_cgroup_csv(struct perf_stat_    
169 {                                                 
170         fprintf(config->output, "%s%s", config    
171 }                                                 
172                                                   
173 static void print_cgroup_json(struct perf_stat    
174 {                                                 
175         fprintf(config->output, "\"cgroup\" :     
176 }                                                 
177                                                   
178 static void print_cgroup(struct perf_stat_conf    
179 {                                                 
180         if (nr_cgroups || config->cgroup_list)    
181                 const char *cgrp_name = cgrp ?    
182                                                   
183                 if (config->json_output)          
184                         print_cgroup_json(conf    
185                 else if (config->csv_output)      
186                         print_cgroup_csv(confi    
187                 else                              
188                         print_cgroup_std(confi    
189         }                                         
190 }                                                 
191                                                   
192 static void print_aggr_id_std(struct perf_stat    
193                               struct evsel *ev    
194 {                                                 
195         FILE *output = config->output;            
196         int idx = config->aggr_mode;              
197         char buf[128];                            
198                                                   
199         switch (config->aggr_mode) {              
200         case AGGR_CORE:                           
201                 snprintf(buf, sizeof(buf), "S%    
202                 break;                            
203         case AGGR_CACHE:                          
204                 snprintf(buf, sizeof(buf), "S%    
205                          id.socket, id.die, id    
206                 break;                            
207         case AGGR_CLUSTER:                        
208                 snprintf(buf, sizeof(buf), "S%    
209                 break;                            
210         case AGGR_DIE:                            
211                 snprintf(buf, sizeof(buf), "S%    
212                 break;                            
213         case AGGR_SOCKET:                         
214                 snprintf(buf, sizeof(buf), "S%    
215                 break;                            
216         case AGGR_NODE:                           
217                 snprintf(buf, sizeof(buf), "N%    
218                 break;                            
219         case AGGR_NONE:                           
220                 if (evsel->percore && !config-    
221                         snprintf(buf, sizeof(b    
222                                 id.socket, id.    
223                         fprintf(output, "%-*s     
224                                 aggr_header_le    
225                 } else if (id.cpu.cpu > -1) {     
226                         fprintf(output, "CPU%-    
227                                 aggr_header_le    
228                 }                                 
229                 return;                           
230         case AGGR_THREAD:                         
231                 fprintf(output, "%*s-%-*d ",      
232                         COMM_LEN, perf_thread_    
233                         PID_LEN, perf_thread_m    
234                 return;                           
235         case AGGR_GLOBAL:                         
236         case AGGR_UNSET:                          
237         case AGGR_MAX:                            
238         default:                                  
239                 return;                           
240         }                                         
241                                                   
242         fprintf(output, "%-*s %*d ", aggr_head    
243 }                                                 
244                                                   
245 static void print_aggr_id_csv(struct perf_stat    
246                               struct evsel *ev    
247 {                                                 
248         FILE *output = config->output;            
249         const char *sep = config->csv_sep;        
250                                                   
251         switch (config->aggr_mode) {              
252         case AGGR_CORE:                           
253                 fprintf(output, "S%d-D%d-C%d%s    
254                         id.socket, id.die, id.    
255                 break;                            
256         case AGGR_CACHE:                          
257                 fprintf(config->output, "S%d-D    
258                         id.socket, id.die, id.    
259                 break;                            
260         case AGGR_CLUSTER:                        
261                 fprintf(config->output, "S%d-D    
262                         id.socket, id.die, id.    
263                 break;                            
264         case AGGR_DIE:                            
265                 fprintf(output, "S%d-D%d%s%d%s    
266                         id.socket, id.die, sep    
267                 break;                            
268         case AGGR_SOCKET:                         
269                 fprintf(output, "S%d%s%d%s",      
270                         id.socket, sep, aggr_n    
271                 break;                            
272         case AGGR_NODE:                           
273                 fprintf(output, "N%d%s%d%s",      
274                         id.node, sep, aggr_nr,    
275                 break;                            
276         case AGGR_NONE:                           
277                 if (evsel->percore && !config-    
278                         fprintf(output, "S%d-D    
279                                 id.socket, id.    
280                 } else if (id.cpu.cpu > -1) {     
281                         fprintf(output, "CPU%d    
282                                 id.cpu.cpu, se    
283                 }                                 
284                 break;                            
285         case AGGR_THREAD:                         
286                 fprintf(output, "%s-%d%s",        
287                         perf_thread_map__comm(    
288                         perf_thread_map__pid(e    
289                         sep);                     
290                 break;                            
291         case AGGR_GLOBAL:                         
292         case AGGR_UNSET:                          
293         case AGGR_MAX:                            
294         default:                                  
295                 break;                            
296         }                                         
297 }                                                 
298                                                   
299 static void print_aggr_id_json(struct perf_sta    
300                                struct evsel *e    
301 {                                                 
302         FILE *output = config->output;            
303                                                   
304         switch (config->aggr_mode) {              
305         case AGGR_CORE:                           
306                 fprintf(output, "\"core\" : \"    
307                         id.socket, id.die, id.    
308                 break;                            
309         case AGGR_CACHE:                          
310                 fprintf(output, "\"cache\" : \    
311                         id.socket, id.die, id.    
312                 break;                            
313         case AGGR_CLUSTER:                        
314                 fprintf(output, "\"cluster\" :    
315                         id.socket, id.die, id.    
316                 break;                            
317         case AGGR_DIE:                            
318                 fprintf(output, "\"die\" : \"S    
319                         id.socket, id.die, agg    
320                 break;                            
321         case AGGR_SOCKET:                         
322                 fprintf(output, "\"socket\" :     
323                         id.socket, aggr_nr);      
324                 break;                            
325         case AGGR_NODE:                           
326                 fprintf(output, "\"node\" : \"    
327                         id.node, aggr_nr);        
328                 break;                            
329         case AGGR_NONE:                           
330                 if (evsel->percore && !config-    
331                         fprintf(output, "\"cor    
332                                 id.socket, id.    
333                 } else if (id.cpu.cpu > -1) {     
334                         fprintf(output, "\"cpu    
335                                 id.cpu.cpu);      
336                 }                                 
337                 break;                            
338         case AGGR_THREAD:                         
339                 fprintf(output, "\"thread\" :     
340                         perf_thread_map__comm(    
341                         perf_thread_map__pid(e    
342                 break;                            
343         case AGGR_GLOBAL:                         
344         case AGGR_UNSET:                          
345         case AGGR_MAX:                            
346         default:                                  
347                 break;                            
348         }                                         
349 }                                                 
350                                                   
351 static void aggr_printout(struct perf_stat_con    
352                           struct evsel *evsel,    
353 {                                                 
354         if (config->json_output)                  
355                 print_aggr_id_json(config, evs    
356         else if (config->csv_output)              
357                 print_aggr_id_csv(config, evse    
358         else                                      
359                 print_aggr_id_std(config, evse    
360 }                                                 
361                                                   
362 struct outstate {                                 
363         FILE *fh;                                 
364         bool newline;                             
365         bool first;                               
366         const char *prefix;                       
367         int  nfields;                             
368         int  aggr_nr;                             
369         struct aggr_cpu_id id;                    
370         struct evsel *evsel;                      
371         struct cgroup *cgrp;                      
372 };                                                
373                                                   
374 static void new_line_std(struct perf_stat_conf    
375                          void *ctx)               
376 {                                                 
377         struct outstate *os = ctx;                
378                                                   
379         os->newline = true;                       
380 }                                                 
381                                                   
382 static inline void __new_line_std_csv(struct p    
383                                       struct o    
384 {                                                 
385         fputc('\n', os->fh);                      
386         if (os->prefix)                           
387                 fputs(os->prefix, os->fh);        
388         aggr_printout(config, os->evsel, os->i    
389 }                                                 
390                                                   
391 static inline void __new_line_std(struct outst    
392 {                                                 
393         fprintf(os->fh, "                         
394 }                                                 
395                                                   
396 static void do_new_line_std(struct perf_stat_c    
397                             struct outstate *o    
398 {                                                 
399         __new_line_std_csv(config, os);           
400         if (config->aggr_mode == AGGR_NONE)       
401                 fprintf(os->fh, "        ");      
402         __new_line_std(os);                       
403 }                                                 
404                                                   
405 static void print_metric_std(struct perf_stat_    
406                              void *ctx, const     
407                              const char *unit,    
408 {                                                 
409         struct outstate *os = ctx;                
410         FILE *out = os->fh;                       
411         int n;                                    
412         bool newline = os->newline;               
413                                                   
414         os->newline = false;                      
415                                                   
416         if (unit == NULL || fmt == NULL) {        
417                 fprintf(out, "%-*s", METRIC_LE    
418                 return;                           
419         }                                         
420                                                   
421         if (newline)                              
422                 do_new_line_std(config, os);      
423                                                   
424         n = fprintf(out, " # ");                  
425         if (color)                                
426                 n += color_fprintf(out, color,    
427         else                                      
428                 n += fprintf(out, fmt, val);      
429         fprintf(out, " %-*s", METRIC_LEN - n -    
430 }                                                 
431                                                   
432 static void new_line_csv(struct perf_stat_conf    
433 {                                                 
434         struct outstate *os = ctx;                
435         int i;                                    
436                                                   
437         __new_line_std_csv(config, os);           
438         for (i = 0; i < os->nfields; i++)         
439                 fputs(config->csv_sep, os->fh)    
440 }                                                 
441                                                   
442 static void print_metric_csv(struct perf_stat_    
443                              void *ctx,           
444                              const char *color    
445                              const char *fmt,     
446 {                                                 
447         struct outstate *os = ctx;                
448         FILE *out = os->fh;                       
449         char buf[64], *vals, *ends;               
450                                                   
451         if (unit == NULL || fmt == NULL) {        
452                 fprintf(out, "%s%s", config->c    
453                 return;                           
454         }                                         
455         snprintf(buf, sizeof(buf), fmt, val);     
456         ends = vals = skip_spaces(buf);           
457         while (isdigit(*ends) || *ends == '.')    
458                 ends++;                           
459         *ends = 0;                                
460         fprintf(out, "%s%s%s%s", config->csv_s    
461 }                                                 
462                                                   
463 static void print_metric_json(struct perf_stat    
464                              void *ctx,           
465                              const char *color    
466                              const char *fmt _    
467                              const char *unit,    
468 {                                                 
469         struct outstate *os = ctx;                
470         FILE *out = os->fh;                       
471                                                   
472         fprintf(out, "\"metric-value\" : \"%f\    
473         fprintf(out, "\"metric-unit\" : \"%s\"    
474         if (!config->metric_only)                 
475                 fprintf(out, "}");                
476 }                                                 
477                                                   
478 static void new_line_json(struct perf_stat_con    
479 {                                                 
480         struct outstate *os = ctx;                
481                                                   
482         fputs("\n{", os->fh);                     
483         if (os->prefix)                           
484                 fprintf(os->fh, "%s", os->pref    
485         aggr_printout(config, os->evsel, os->i    
486 }                                                 
487                                                   
488 static void print_metricgroup_header_json(stru    
489                                           void    
490                                           cons    
491 {                                                 
492         if (!metricgroup_name)                    
493                 return;                           
494                                                   
495         fprintf(config->output, "\"metricgroup    
496         new_line_json(config, ctx);               
497 }                                                 
498                                                   
499 static void print_metricgroup_header_csv(struc    
500                                          void     
501                                          const    
502 {                                                 
503         struct outstate *os = ctx;                
504         int i;                                    
505                                                   
506         if (!metricgroup_name) {                  
507                 /* Leave space for running and    
508                 for (i = 0; i < os->nfields -     
509                         fputs(config->csv_sep,    
510                 return;                           
511         }                                         
512                                                   
513         for (i = 0; i < os->nfields; i++)         
514                 fputs(config->csv_sep, os->fh)    
515         fprintf(config->output, "%s", metricgr    
516         new_line_csv(config, ctx);                
517 }                                                 
518                                                   
519 static void print_metricgroup_header_std(struc    
520                                          void     
521                                          const    
522 {                                                 
523         struct outstate *os = ctx;                
524         int n;                                    
525                                                   
526         if (!metricgroup_name) {                  
527                 __new_line_std(os);               
528                 return;                           
529         }                                         
530                                                   
531         n = fprintf(config->output, " %*s", EV    
532                                                   
533         fprintf(config->output, "%*s", MGROUP_    
534 }                                                 
535                                                   
536 /* Filter out some columns that don't work wel    
537                                                   
538 static bool valid_only_metric(const char *unit    
539 {                                                 
540         if (!unit)                                
541                 return false;                     
542         if (strstr(unit, "/sec") ||               
543             strstr(unit, "CPUs utilized"))        
544                 return false;                     
545         return true;                              
546 }                                                 
547                                                   
548 static const char *fixunit(char *buf, struct e    
549                            const char *unit)      
550 {                                                 
551         if (!strncmp(unit, "of all", 6)) {        
552                 snprintf(buf, 1024, "%s %s", e    
553                          unit);                   
554                 return buf;                       
555         }                                         
556         return unit;                              
557 }                                                 
558                                                   
559 static void print_metric_only(struct perf_stat    
560                               void *ctx, const    
561                               const char *unit    
562 {                                                 
563         struct outstate *os = ctx;                
564         FILE *out = os->fh;                       
565         char buf[1024], str[1024];                
566         unsigned mlen = config->metric_only_le    
567                                                   
568         if (!valid_only_metric(unit))             
569                 return;                           
570         unit = fixunit(buf, os->evsel, unit);     
571         if (mlen < strlen(unit))                  
572                 mlen = strlen(unit) + 1;          
573                                                   
574         if (color)                                
575                 mlen += strlen(color) + sizeof    
576                                                   
577         color_snprintf(str, sizeof(str), color    
578         fprintf(out, "%*s ", mlen, str);          
579         os->first = false;                        
580 }                                                 
581                                                   
582 static void print_metric_only_csv(struct perf_    
583                                   void *ctx, c    
584                                   const char *    
585                                   const char *    
586 {                                                 
587         struct outstate *os = ctx;                
588         FILE *out = os->fh;                       
589         char buf[64], *vals, *ends;               
590         char tbuf[1024];                          
591                                                   
592         if (!valid_only_metric(unit))             
593                 return;                           
594         unit = fixunit(tbuf, os->evsel, unit);    
595         snprintf(buf, sizeof(buf), fmt ?: "",     
596         ends = vals = skip_spaces(buf);           
597         while (isdigit(*ends) || *ends == '.')    
598                 ends++;                           
599         *ends = 0;                                
600         fprintf(out, "%s%s", vals, config->csv    
601         os->first = false;                        
602 }                                                 
603                                                   
604 static void print_metric_only_json(struct perf    
605                                   void *ctx, c    
606                                   const char *    
607                                   const char *    
608 {                                                 
609         struct outstate *os = ctx;                
610         FILE *out = os->fh;                       
611         char buf[64], *vals, *ends;               
612         char tbuf[1024];                          
613                                                   
614         if (!valid_only_metric(unit))             
615                 return;                           
616         unit = fixunit(tbuf, os->evsel, unit);    
617         snprintf(buf, sizeof(buf), fmt ?: "",     
618         ends = vals = skip_spaces(buf);           
619         while (isdigit(*ends) || *ends == '.')    
620                 ends++;                           
621         *ends = 0;                                
622         if (!unit[0] || !vals[0])                 
623                 return;                           
624         fprintf(out, "%s\"%s\" : \"%s\"", os->    
625         os->first = false;                        
626 }                                                 
627                                                   
628 static void new_line_metric(struct perf_stat_c    
629                             void *ctx __maybe_    
630 {                                                 
631 }                                                 
632                                                   
633 static void print_metric_header(struct perf_st    
634                                 void *ctx, con    
635                                 const char *fm    
636                                 const char *un    
637 {                                                 
638         struct outstate *os = ctx;                
639         char tbuf[1024];                          
640                                                   
641         /* In case of iostat, print metric hea    
642         if (config->iostat_run &&                 
643             os->evsel->priv != os->evsel->evli    
644                 return;                           
645                                                   
646         if (os->evsel->cgrp != os->cgrp)          
647                 return;                           
648                                                   
649         if (!valid_only_metric(unit))             
650                 return;                           
651         unit = fixunit(tbuf, os->evsel, unit);    
652                                                   
653         if (config->json_output)                  
654                 return;                           
655         else if (config->csv_output)              
656                 fprintf(os->fh, "%s%s", unit,     
657         else                                      
658                 fprintf(os->fh, "%*s ", config    
659 }                                                 
660                                                   
661 static void print_counter_value_std(struct per    
662                                     struct evs    
663 {                                                 
664         FILE *output = config->output;            
665         double sc =  evsel->scale;                
666         const char *fmt;                          
667         const char *bad_count = evsel->support    
668                                                   
669         if (config->big_num)                      
670                 fmt = floor(sc) != sc ? "%'*.2    
671         else                                      
672                 fmt = floor(sc) != sc ? "%*.2f    
673                                                   
674         if (ok)                                   
675                 fprintf(output, fmt, COUNTS_LE    
676         else                                      
677                 fprintf(output, "%*s ", COUNTS    
678                                                   
679         if (evsel->unit)                          
680                 fprintf(output, "%-*s ", confi    
681                                                   
682         fprintf(output, "%-*s", EVNAME_LEN, ev    
683 }                                                 
684                                                   
685 static void print_counter_value_csv(struct per    
686                                     struct evs    
687 {                                                 
688         FILE *output = config->output;            
689         double sc =  evsel->scale;                
690         const char *sep = config->csv_sep;        
691         const char *fmt = floor(sc) != sc ? "%    
692         const char *bad_count = evsel->support    
693                                                   
694         if (ok)                                   
695                 fprintf(output, fmt, avg, sep)    
696         else                                      
697                 fprintf(output, "%s%s", bad_co    
698                                                   
699         if (evsel->unit)                          
700                 fprintf(output, "%s%s", evsel-    
701                                                   
702         fprintf(output, "%s", evsel__name(evse    
703 }                                                 
704                                                   
705 static void print_counter_value_json(struct pe    
706                                      struct ev    
707 {                                                 
708         FILE *output = config->output;            
709         const char *bad_count = evsel->support    
710                                                   
711         if (ok)                                   
712                 fprintf(output, "\"counter-val    
713         else                                      
714                 fprintf(output, "\"counter-val    
715                                                   
716         if (evsel->unit)                          
717                 fprintf(output, "\"unit\" : \"    
718                                                   
719         fprintf(output, "\"event\" : \"%s\", "    
720 }                                                 
721                                                   
722 static void print_counter_value(struct perf_st    
723                                 struct evsel *    
724 {                                                 
725         if (config->json_output)                  
726                 print_counter_value_json(confi    
727         else if (config->csv_output)              
728                 print_counter_value_csv(config    
729         else                                      
730                 print_counter_value_std(config    
731 }                                                 
732                                                   
733 static void abs_printout(struct perf_stat_conf    
734                          struct aggr_cpu_id id    
735                          struct evsel *evsel,     
736 {                                                 
737         aggr_printout(config, evsel, id, aggr_    
738         print_counter_value(config, evsel, avg    
739         print_cgroup(config, evsel->cgrp);        
740 }                                                 
741                                                   
742 static bool is_mixed_hw_group(struct evsel *co    
743 {                                                 
744         struct evlist *evlist = counter->evlis    
745         u32 pmu_type = counter->core.attr.type    
746         struct evsel *pos;                        
747                                                   
748         if (counter->core.nr_members < 2)         
749                 return false;                     
750                                                   
751         evlist__for_each_entry(evlist, pos) {     
752                 /* software events can be part    
753                 if (pos->core.attr.type == PER    
754                         continue;                 
755                 if (pmu_type == PERF_TYPE_SOFT    
756                         pmu_type = pos->core.a    
757                         continue;                 
758                 }                                 
759                 if (pmu_type != pos->core.attr    
760                         return true;              
761         }                                         
762                                                   
763         return false;                             
764 }                                                 
765                                                   
766 static bool evlist__has_hybrid(struct evlist *    
767 {                                                 
768         struct evsel *evsel;                      
769                                                   
770         if (perf_pmus__num_core_pmus() == 1)      
771                 return false;                     
772                                                   
773         evlist__for_each_entry(evlist, evsel)     
774                 if (evsel->core.is_pmu_core)      
775                         return true;              
776         }                                         
777                                                   
778         return false;                             
779 }                                                 
780                                                   
781 static void printout(struct perf_stat_config *    
782                      double uval, u64 run, u64    
783 {                                                 
784         struct perf_stat_output_ctx out;          
785         print_metric_t pm;                        
786         new_line_t nl;                            
787         print_metricgroup_header_t pmh;           
788         bool ok = true;                           
789         struct evsel *counter = os->evsel;        
790                                                   
791         if (config->csv_output) {                 
792                 pm = config->metric_only ? pri    
793                 nl = config->metric_only ? new    
794                 pmh = print_metricgroup_header    
795                 os->nfields = 4 + (counter->cg    
796         } else if (config->json_output) {         
797                 pm = config->metric_only ? pri    
798                 nl = config->metric_only ? new    
799                 pmh = print_metricgroup_header    
800         } else {                                  
801                 pm = config->metric_only ? pri    
802                 nl = config->metric_only ? new    
803                 pmh = print_metricgroup_header    
804         }                                         
805                                                   
806         if (run == 0 || ena == 0 || counter->c    
807                 if (config->metric_only) {        
808                         pm(config, os, NULL, "    
809                         return;                   
810                 }                                 
811                                                   
812                 ok = false;                       
813                                                   
814                 if (counter->supported) {         
815                         if (!evlist__has_hybri    
816                                 config->print_    
817                                 if (is_mixed_h    
818                                         config    
819                         }                         
820                 }                                 
821         }                                         
822                                                   
823         out.print_metric = pm;                    
824         out.new_line = nl;                        
825         out.print_metricgroup_header = pmh;       
826         out.ctx = os;                             
827         out.force_header = false;                 
828                                                   
829         if (!config->metric_only && !counter->    
830                 abs_printout(config, os->id, o    
831                                                   
832                 print_noise(config, counter, n    
833                 print_running(config, run, ena    
834         }                                         
835                                                   
836         if (ok) {                                 
837                 if (!config->metric_only && co    
838                         void *from = NULL;        
839                                                   
840                         aggr_printout(config,     
841                         /* Print out all the m    
842                         do {                      
843                                 int num = 0;      
844                                                   
845                                 /* Print out t    
846                                 if (from) {       
847                                         if (co    
848                                                   
849                                         else      
850                                                   
851                                 }                 
852                                                   
853                                 print_noise(co    
854                                 print_running(    
855                                 from = perf_st    
856                                                   
857                                                   
858                         } while (from != NULL)    
859                 } else                            
860                         perf_stat__print_shado    
861                                                   
862         } else {                                  
863                 pm(config, os, /*color=*/NULL,    
864         }                                         
865                                                   
866         if (!config->metric_only) {               
867                 print_noise(config, counter, n    
868                 print_running(config, run, ena    
869         }                                         
870 }                                                 
871                                                   
872 static void uniquify_event_name(struct evsel *    
873 {                                                 
874         char *new_name;                           
875         char *config;                             
876         int ret = 0;                              
877                                                   
878         if (counter->uniquified_name || counte    
879             !counter->pmu_name || !strncmp(evs    
880                                            str    
881                 return;                           
882                                                   
883         config = strchr(counter->name, '/');      
884         if (config) {                             
885                 if (asprintf(&new_name,           
886                              "%s%s", counter->    
887                         free(counter->name);      
888                         counter->name = new_na    
889                 }                                 
890         } else {                                  
891                 if (evsel__is_hybrid(counter))    
892                         ret = asprintf(&new_na    
893                                        counter    
894                 } else {                          
895                         ret = asprintf(&new_na    
896                                        counter    
897                 }                                 
898                                                   
899                 if (ret) {                        
900                         free(counter->name);      
901                         counter->name = new_na    
902                 }                                 
903         }                                         
904                                                   
905         counter->uniquified_name = true;          
906 }                                                 
907                                                   
908 static bool hybrid_uniquify(struct evsel *evse    
909 {                                                 
910         return evsel__is_hybrid(evsel) && !con    
911 }                                                 
912                                                   
913 static void uniquify_counter(struct perf_stat_    
914 {                                                 
915         if (config->aggr_mode == AGGR_NONE ||     
916                 uniquify_event_name(counter);     
917 }                                                 
918                                                   
919 /**                                               
920  * should_skip_zero_count() - Check if the eve    
921  * @config: The perf stat configuration (inclu    
922  * @counter: The evsel with its associated cpu    
923  * @id: The aggregation id that is being queri    
924  *                                                
925  * Due to mismatch between the event cpumap or    
926  * aggregation mode, sometimes it'd iterate th    
927  * which does not contain any values.             
928  *                                                
929  * For example, uncore events have dedicated C    
930  * result for other CPUs should be zero and sk    
931  *                                                
932  * Return: %true if the value should NOT be pr    
933  * needs to be printed like "<not counted>" or    
934  */                                               
935 static bool should_skip_zero_counter(struct pe    
936                                      struct ev    
937                                      const str    
938 {                                                 
939         struct perf_cpu cpu;                      
940         int idx;                                  
941                                                   
942         /*                                        
943          * Skip value 0 when enabling --per-th    
944          * otherwise it will have too many 0 o    
945          */                                       
946         if (config->aggr_mode == AGGR_THREAD &    
947                 return true;                      
948                                                   
949         /* Tool events have the software PMU b    
950         if (evsel__is_tool(counter))              
951                 return true;                      
952                                                   
953         /*                                        
954          * Skip value 0 when it's an uncore ev    
955          * does not belong to the PMU cpumask.    
956          */                                       
957         if (!counter->pmu || !counter->pmu->is    
958                 return false;                     
959                                                   
960         perf_cpu_map__for_each_cpu(cpu, idx, c    
961                 struct aggr_cpu_id own_id = co    
962                                                   
963                 if (aggr_cpu_id__equal(id, &ow    
964                         return false;             
965         }                                         
966         return true;                              
967 }                                                 
968                                                   
969 static void print_counter_aggrdata(struct perf    
970                                    struct evse    
971                                    struct outs    
972 {                                                 
973         FILE *output = config->output;            
974         u64 ena, run, val;                        
975         double uval;                              
976         struct perf_stat_evsel *ps = counter->    
977         struct perf_stat_aggr *aggr = &ps->agg    
978         struct aggr_cpu_id id = config->aggr_m    
979         double avg = aggr->counts.val;            
980         bool metric_only = config->metric_only    
981                                                   
982         os->id = id;                              
983         os->aggr_nr = aggr->nr;                   
984         os->evsel = counter;                      
985                                                   
986         /* Skip already merged uncore/hybrid e    
987         if (counter->merged_stat)                 
988                 return;                           
989                                                   
990         uniquify_counter(config, counter);        
991                                                   
992         val = aggr->counts.val;                   
993         ena = aggr->counts.ena;                   
994         run = aggr->counts.run;                   
995                                                   
996         if (perf_stat__skip_metric_event(count    
997                 return;                           
998                                                   
999         if (val == 0 && should_skip_zero_count    
1000                 return;                          
1001                                                  
1002         if (!metric_only) {                      
1003                 if (config->json_output)         
1004                         fputc('{', output);      
1005                 if (os->prefix)                  
1006                         fprintf(output, "%s",    
1007                 else if (config->summary && c    
1008                          !config->no_csv_summ    
1009                         fprintf(output, "%s%s    
1010         }                                        
1011                                                  
1012         uval = val * counter->scale;             
1013                                                  
1014         printout(config, os, uval, run, ena,     
1015                                                  
1016         if (!metric_only)                        
1017                 fputc('\n', output);             
1018 }                                                
1019                                                  
1020 static void print_metric_begin(struct perf_st    
1021                                struct evlist     
1022                                struct outstat    
1023 {                                                
1024         struct perf_stat_aggr *aggr;             
1025         struct aggr_cpu_id id;                   
1026         struct evsel *evsel;                     
1027                                                  
1028         os->first = true;                        
1029         if (!config->metric_only)                
1030                 return;                          
1031                                                  
1032         if (config->json_output)                 
1033                 fputc('{', config->output);      
1034         if (os->prefix)                          
1035                 fprintf(config->output, "%s",    
1036                                                  
1037         evsel = evlist__first(evlist);           
1038         id = config->aggr_map->map[aggr_idx];    
1039         aggr = &evsel->stats->aggr[aggr_idx];    
1040         aggr_printout(config, evsel, id, aggr    
1041                                                  
1042         print_cgroup(config, os->cgrp ? : evs    
1043 }                                                
1044                                                  
1045 static void print_metric_end(struct perf_stat    
1046 {                                                
1047         FILE *output = config->output;           
1048                                                  
1049         if (!config->metric_only)                
1050                 return;                          
1051                                                  
1052         if (config->json_output) {               
1053                 if (os->first)                   
1054                         fputs("\"metric-value    
1055                 fputc('}', output);              
1056         }                                        
1057         fputc('\n', output);                     
1058 }                                                
1059                                                  
1060 static void print_aggr(struct perf_stat_confi    
1061                        struct evlist *evlist,    
1062                        struct outstate *os)      
1063 {                                                
1064         struct evsel *counter;                   
1065         int aggr_idx;                            
1066                                                  
1067         if (!config->aggr_map || !config->agg    
1068                 return;                          
1069                                                  
1070         /*                                       
1071          * With metric_only everything is on     
1072          * Without each counter has its own l    
1073          */                                      
1074         cpu_aggr_map__for_each_idx(aggr_idx,     
1075                 print_metric_begin(config, ev    
1076                                                  
1077                 evlist__for_each_entry(evlist    
1078                         print_counter_aggrdat    
1079                 }                                
1080                 print_metric_end(config, os);    
1081         }                                        
1082 }                                                
1083                                                  
1084 static void print_aggr_cgroup(struct perf_sta    
1085                               struct evlist *    
1086                               struct outstate    
1087 {                                                
1088         struct evsel *counter, *evsel;           
1089         int aggr_idx;                            
1090                                                  
1091         if (!config->aggr_map || !config->agg    
1092                 return;                          
1093                                                  
1094         evlist__for_each_entry(evlist, evsel)    
1095                 if (os->cgrp == evsel->cgrp)     
1096                         continue;                
1097                                                  
1098                 os->cgrp = evsel->cgrp;          
1099                                                  
1100                 cpu_aggr_map__for_each_idx(ag    
1101                         print_metric_begin(co    
1102                                                  
1103                         evlist__for_each_entr    
1104                                 if (counter->    
1105                                         conti    
1106                                                  
1107                                 print_counter    
1108                         }                        
1109                         print_metric_end(conf    
1110                 }                                
1111         }                                        
1112 }                                                
1113                                                  
1114 static void print_counter(struct perf_stat_co    
1115                           struct evsel *count    
1116 {                                                
1117         int aggr_idx;                            
1118                                                  
1119         /* AGGR_THREAD doesn't have config->a    
1120         if (!config->aggr_map)                   
1121                 return;                          
1122                                                  
1123         cpu_aggr_map__for_each_idx(aggr_idx,     
1124                 print_counter_aggrdata(config    
1125         }                                        
1126 }                                                
1127                                                  
1128 static void print_no_aggr_metric(struct perf_    
1129                                  struct evlis    
1130                                  struct outst    
1131 {                                                
1132         int all_idx;                             
1133         struct perf_cpu cpu;                     
1134                                                  
1135         perf_cpu_map__for_each_cpu(cpu, all_i    
1136                 struct evsel *counter;           
1137                 bool first = true;               
1138                                                  
1139                 evlist__for_each_entry(evlist    
1140                         u64 ena, run, val;       
1141                         double uval;             
1142                         struct perf_stat_evse    
1143                         int aggr_idx = 0;        
1144                                                  
1145                         if (!perf_cpu_map__ha    
1146                                 continue;        
1147                                                  
1148                         cpu_aggr_map__for_eac    
1149                                 if (config->a    
1150                                         break    
1151                         }                        
1152                                                  
1153                         os->evsel = counter;     
1154                         os->id = aggr_cpu_id_    
1155                         if (first) {             
1156                                 print_metric_    
1157                                 first = false    
1158                         }                        
1159                         val = ps->aggr[aggr_i    
1160                         ena = ps->aggr[aggr_i    
1161                         run = ps->aggr[aggr_i    
1162                                                  
1163                         uval = val * counter-    
1164                         printout(config, os,     
1165                 }                                
1166                 if (!first)                      
1167                         print_metric_end(conf    
1168         }                                        
1169 }                                                
1170                                                  
1171 static void print_metric_headers_std(struct p    
1172                                      bool no_    
1173 {                                                
1174         fputc(' ', config->output);              
1175                                                  
1176         if (!no_indent) {                        
1177                 int len = aggr_header_lens[co    
1178                                                  
1179                 if (nr_cgroups || config->cgr    
1180                         len += CGROUP_LEN + 1    
1181                                                  
1182                 fprintf(config->output, "%*s"    
1183         }                                        
1184 }                                                
1185                                                  
1186 static void print_metric_headers_csv(struct p    
1187                                      bool no_    
1188 {                                                
1189         const char *p;                           
1190                                                  
1191         if (config->interval)                    
1192                 fprintf(config->output, "time    
1193         if (config->iostat_run)                  
1194                 return;                          
1195                                                  
1196         p = aggr_header_csv[config->aggr_mode    
1197         while (*p) {                             
1198                 if (*p == ',')                   
1199                         fputs(config->csv_sep    
1200                 else                             
1201                         fputc(*p, config->out    
1202                 p++;                             
1203         }                                        
1204 }                                                
1205                                                  
1206 static void print_metric_headers_json(struct     
1207                                       bool no    
1208 {                                                
1209 }                                                
1210                                                  
1211 static void print_metric_headers(struct perf_    
1212                                  struct evlis    
1213 {                                                
1214         struct evsel *counter;                   
1215         struct outstate os = {                   
1216                 .fh = config->output             
1217         };                                       
1218         struct perf_stat_output_ctx out = {      
1219                 .ctx = &os,                      
1220                 .print_metric = print_metric_    
1221                 .new_line = new_line_metric,     
1222                 .force_header = true,            
1223         };                                       
1224                                                  
1225         if (config->json_output)                 
1226                 print_metric_headers_json(con    
1227         else if (config->csv_output)             
1228                 print_metric_headers_csv(conf    
1229         else                                     
1230                 print_metric_headers_std(conf    
1231                                                  
1232         if (config->iostat_run)                  
1233                 iostat_print_header_prefix(co    
1234                                                  
1235         if (config->cgroup_list)                 
1236                 os.cgrp = evlist__first(evlis    
1237                                                  
1238         /* Print metrics headers only */         
1239         evlist__for_each_entry(evlist, counte    
1240                 if (!config->iostat_run &&       
1241                     config->aggr_mode != AGGR    
1242                         continue;                
1243                                                  
1244                 os.evsel = counter;              
1245                                                  
1246                 perf_stat__print_shadow_stats    
1247                                                  
1248                                                  
1249                                                  
1250         }                                        
1251                                                  
1252         if (!config->json_output)                
1253                 fputc('\n', config->output);     
1254 }                                                
1255                                                  
1256 static void prepare_interval(struct perf_stat    
1257                              char *prefix, si    
1258 {                                                
1259         if (config->iostat_run)                  
1260                 return;                          
1261                                                  
1262         if (config->json_output)                 
1263                 scnprintf(prefix, len, "\"int    
1264                           (unsigned long) ts-    
1265         else if (config->csv_output)             
1266                 scnprintf(prefix, len, "%lu.%    
1267                           (unsigned long) ts-    
1268         else                                     
1269                 scnprintf(prefix, len, "%6lu.    
1270                           (unsigned long) ts-    
1271 }                                                
1272                                                  
1273 static void print_header_interval_std(struct     
1274                                       struct     
1275                                       struct     
1276                                       int arg    
1277                                       const c    
1278 {                                                
1279         FILE *output = config->output;           
1280                                                  
1281         switch (config->aggr_mode) {             
1282         case AGGR_NODE:                          
1283         case AGGR_SOCKET:                        
1284         case AGGR_DIE:                           
1285         case AGGR_CLUSTER:                       
1286         case AGGR_CACHE:                         
1287         case AGGR_CORE:                          
1288                 fprintf(output, "#%*s %-*s cp    
1289                         INTERVAL_LEN - 1, "ti    
1290                         aggr_header_lens[conf    
1291                         aggr_header_std[confi    
1292                 break;                           
1293         case AGGR_NONE:                          
1294                 fprintf(output, "#%*s %-*s",     
1295                         INTERVAL_LEN - 1, "ti    
1296                         aggr_header_lens[conf    
1297                         aggr_header_std[confi    
1298                 break;                           
1299         case AGGR_THREAD:                        
1300                 fprintf(output, "#%*s %*s-%-*    
1301                         INTERVAL_LEN - 1, "ti    
1302                         COMM_LEN, "comm", PID    
1303                 break;                           
1304         case AGGR_GLOBAL:                        
1305         default:                                 
1306                 if (!config->iostat_run)         
1307                         fprintf(output, "#%*s    
1308                                 INTERVAL_LEN     
1309         case AGGR_UNSET:                         
1310         case AGGR_MAX:                           
1311                 break;                           
1312         }                                        
1313                                                  
1314         if (config->metric_only)                 
1315                 print_metric_headers(config,     
1316         else                                     
1317                 fprintf(output, " %*s %*s eve    
1318                         COUNTS_LEN, "counts",    
1319 }                                                
1320                                                  
1321 static void print_header_std(struct perf_stat    
1322                              struct target *_    
1323                              int argc, const     
1324 {                                                
1325         FILE *output = config->output;           
1326         int i;                                   
1327                                                  
1328         fprintf(output, "\n");                   
1329         fprintf(output, " Performance counter    
1330         if (_target->bpf_str)                    
1331                 fprintf(output, "\'BPF progra    
1332         else if (_target->system_wide)           
1333                 fprintf(output, "\'system wid    
1334         else if (_target->cpu_list)              
1335                 fprintf(output, "\'CPU(s) %s"    
1336         else if (!target__has_task(_target))     
1337                 fprintf(output, "\'%s", argv     
1338                 for (i = 1; argv && (i < argc    
1339                         fprintf(output, " %s"    
1340         } else if (_target->pid)                 
1341                 fprintf(output, "process id \    
1342         else                                     
1343                 fprintf(output, "thread id \'    
1344                                                  
1345         fprintf(output, "\'");                   
1346         if (config->run_count > 1)               
1347                 fprintf(output, " (%d runs)",    
1348         fprintf(output, ":\n\n");                
1349                                                  
1350         if (config->metric_only)                 
1351                 print_metric_headers(config,     
1352 }                                                
1353                                                  
1354 static void print_header_csv(struct perf_stat    
1355                              struct target *_    
1356                              struct evlist *e    
1357                              int argc __maybe    
1358                              const char **arg    
1359 {                                                
1360         if (config->metric_only)                 
1361                 print_metric_headers(config,     
1362 }                                                
1363 static void print_header_json(struct perf_sta    
1364                               struct target *    
1365                               struct evlist *    
1366                               int argc __mayb    
1367                               const char **ar    
1368 {                                                
1369         if (config->metric_only)                 
1370                 print_metric_headers(config,     
1371 }                                                
1372                                                  
1373 static void print_header(struct perf_stat_con    
1374                          struct target *_targ    
1375                          struct evlist *evlis    
1376                          int argc, const char    
1377 {                                                
1378         static int num_print_iv;                 
1379                                                  
1380         fflush(stdout);                          
1381                                                  
1382         if (config->interval_clear)              
1383                 puts(CONSOLE_CLEAR);             
1384                                                  
1385         if (num_print_iv == 0 || config->inte    
1386                 if (config->json_output)         
1387                         print_header_json(con    
1388                 else if (config->csv_output)     
1389                         print_header_csv(conf    
1390                 else if (config->interval)       
1391                         print_header_interval    
1392                 else                             
1393                         print_header_std(conf    
1394         }                                        
1395                                                  
1396         if (num_print_iv++ == 25)                
1397                 num_print_iv = 0;                
1398 }                                                
1399                                                  
1400 static int get_precision(double num)             
1401 {                                                
1402         if (num > 1)                             
1403                 return 0;                        
1404                                                  
1405         return lround(ceil(-log10(num)));        
1406 }                                                
1407                                                  
1408 static void print_table(struct perf_stat_conf    
1409                         FILE *output, int pre    
1410 {                                                
1411         char tmp[64];                            
1412         int idx, indent = 0;                     
1413                                                  
1414         scnprintf(tmp, 64, " %17.*f", precisi    
1415         while (tmp[indent] == ' ')               
1416                 indent++;                        
1417                                                  
1418         fprintf(output, "%*s# Table of indivi    
1419                                                  
1420         for (idx = 0; idx < config->run_count    
1421                 double run = (double) config-    
1422                 int h, n = 1 + abs((int) (100    
1423                                                  
1424                 fprintf(output, " %17.*f (%+.    
1425                         precision, run, preci    
1426                                                  
1427                 for (h = 0; h < n; h++)          
1428                         fprintf(output, "#");    
1429                                                  
1430                 fprintf(output, "\n");           
1431         }                                        
1432                                                  
1433         fprintf(output, "\n%*s# Final result:    
1434 }                                                
1435                                                  
1436 static double timeval2double(struct timeval *    
1437 {                                                
1438         return t->tv_sec + (double) t->tv_use    
1439 }                                                
1440                                                  
1441 static void print_footer(struct perf_stat_con    
1442 {                                                
1443         double avg = avg_stats(config->wallti    
1444         FILE *output = config->output;           
1445                                                  
1446         if (config->interval || config->csv_o    
1447                 return;                          
1448                                                  
1449         if (!config->null_run)                   
1450                 fprintf(output, "\n");           
1451                                                  
1452         if (config->run_count == 1) {            
1453                 fprintf(output, " %17.9f seco    
1454                                                  
1455                 if (config->ru_display) {        
1456                         double ru_utime = tim    
1457                         double ru_stime = tim    
1458                                                  
1459                         fprintf(output, "\n\n    
1460                         fprintf(output, " %17    
1461                         fprintf(output, " %17    
1462                 }                                
1463         } else {                                 
1464                 double sd = stddev_stats(conf    
1465                 /*                               
1466                  * Display at most 2 more sig    
1467                  * digits than the stddev ina    
1468                  */                              
1469                 int precision = get_precision    
1470                                                  
1471                 if (config->walltime_run_tabl    
1472                         print_table(config, o    
1473                                                  
1474                 fprintf(output, " %17.*f +- %    
1475                         precision, avg, preci    
1476                                                  
1477                 print_noise_pct(config, sd, a    
1478         }                                        
1479         fprintf(output, "\n\n");                 
1480                                                  
1481         if (config->print_free_counters_hint     
1482                 fprintf(output,                  
1483 "Some events weren't counted. Try disabling t    
1484 "       echo 0 > /proc/sys/kernel/nmi_watchdo    
1485 "       perf stat ...\n"                         
1486 "       echo 1 > /proc/sys/kernel/nmi_watchdo    
1487                                                  
1488         if (config->print_mixed_hw_group_erro    
1489                 fprintf(output,                  
1490                         "The events in group     
1491                         "the same PMU. Try re    
1492 }                                                
1493                                                  
1494 static void print_percore(struct perf_stat_co    
1495                           struct evsel *count    
1496 {                                                
1497         bool metric_only = config->metric_onl    
1498         FILE *output = config->output;           
1499         struct cpu_aggr_map *core_map;           
1500         int aggr_idx, core_map_len = 0;          
1501                                                  
1502         if (!config->aggr_map || !config->agg    
1503                 return;                          
1504                                                  
1505         if (config->percore_show_thread)         
1506                 return print_counter(config,     
1507                                                  
1508         /*                                       
1509          * core_map will hold the aggr_cpu_id    
1510          * printed so that each core is print    
1511          */                                      
1512         core_map = cpu_aggr_map__empty_new(co    
1513         if (core_map == NULL) {                  
1514                 fprintf(output, "Cannot alloc    
1515                 return;                          
1516         }                                        
1517                                                  
1518         cpu_aggr_map__for_each_idx(aggr_idx,     
1519                 struct perf_cpu curr_cpu = co    
1520                 struct aggr_cpu_id core_id =     
1521                 bool found = false;              
1522                                                  
1523                 for (int i = 0; i < core_map_    
1524                         if (aggr_cpu_id__equa    
1525                                 found = true;    
1526                                 break;           
1527                         }                        
1528                 }                                
1529                 if (found)                       
1530                         continue;                
1531                                                  
1532                 print_counter_aggrdata(config    
1533                                                  
1534                 core_map->map[core_map_len++]    
1535         }                                        
1536         free(core_map);                          
1537                                                  
1538         if (metric_only)                         
1539                 fputc('\n', output);             
1540 }                                                
1541                                                  
1542 static void print_cgroup_counter(struct perf_    
1543                                  struct outst    
1544 {                                                
1545         struct evsel *counter;                   
1546                                                  
1547         evlist__for_each_entry(evlist, counte    
1548                 if (os->cgrp != counter->cgrp    
1549                         if (os->cgrp != NULL)    
1550                                 print_metric_    
1551                                                  
1552                         os->cgrp = counter->c    
1553                         print_metric_begin(co    
1554                 }                                
1555                                                  
1556                 print_counter(config, counter    
1557         }                                        
1558         if (os->cgrp)                            
1559                 print_metric_end(config, os);    
1560 }                                                
1561                                                  
1562 void evlist__print_counters(struct evlist *ev    
1563                             struct target *_t    
1564                             int argc, const c    
1565 {                                                
1566         bool metric_only = config->metric_onl    
1567         int interval = config->interval;         
1568         struct evsel *counter;                   
1569         char buf[64];                            
1570         struct outstate os = {                   
1571                 .fh = config->output,            
1572                 .first = true,                   
1573         };                                       
1574                                                  
1575         if (config->iostat_run)                  
1576                 evlist->selected = evlist__fi    
1577                                                  
1578         if (interval) {                          
1579                 os.prefix = buf;                 
1580                 prepare_interval(config, buf,    
1581         }                                        
1582                                                  
1583         print_header(config, _target, evlist,    
1584                                                  
1585         switch (config->aggr_mode) {             
1586         case AGGR_CORE:                          
1587         case AGGR_CACHE:                         
1588         case AGGR_CLUSTER:                       
1589         case AGGR_DIE:                           
1590         case AGGR_SOCKET:                        
1591         case AGGR_NODE:                          
1592                 if (config->cgroup_list)         
1593                         print_aggr_cgroup(con    
1594                 else                             
1595                         print_aggr(config, ev    
1596                 break;                           
1597         case AGGR_THREAD:                        
1598         case AGGR_GLOBAL:                        
1599                 if (config->iostat_run) {        
1600                         iostat_print_counters    
1601                                                  
1602                 } else if (config->cgroup_lis    
1603                         print_cgroup_counter(    
1604                 } else {                         
1605                         print_metric_begin(co    
1606                         evlist__for_each_entr    
1607                                 print_counter    
1608                         }                        
1609                         print_metric_end(conf    
1610                 }                                
1611                 break;                           
1612         case AGGR_NONE:                          
1613                 if (metric_only)                 
1614                         print_no_aggr_metric(    
1615                 else {                           
1616                         evlist__for_each_entr    
1617                                 if (counter->    
1618                                         print    
1619                                 else             
1620                                         print    
1621                         }                        
1622                 }                                
1623                 break;                           
1624         case AGGR_MAX:                           
1625         case AGGR_UNSET:                         
1626         default:                                 
1627                 break;                           
1628         }                                        
1629                                                  
1630         print_footer(config);                    
1631                                                  
1632         fflush(config->output);                  
1633 }                                                
1634                                                  

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php