@@ -1182,11 +1182,46 @@ static void aggr_update_shadow(void)
1182
1182
}
1183
1183
}
1184
1184
1185
+ static void collect_data (struct perf_evsel * counter ,
1186
+ void (* cb )(struct perf_evsel * counter , void * data ,
1187
+ bool first ),
1188
+ void * data )
1189
+ {
1190
+ cb (counter , data , true);
1191
+ }
1192
+
1193
+ struct aggr_data {
1194
+ u64 ena , run , val ;
1195
+ int id ;
1196
+ int nr ;
1197
+ int cpu ;
1198
+ };
1199
+
1200
+ static void aggr_cb (struct perf_evsel * counter , void * data , bool first )
1201
+ {
1202
+ struct aggr_data * ad = data ;
1203
+ int cpu , s2 ;
1204
+
1205
+ for (cpu = 0 ; cpu < perf_evsel__nr_cpus (counter ); cpu ++ ) {
1206
+ struct perf_counts_values * counts ;
1207
+
1208
+ s2 = aggr_get_id (perf_evsel__cpus (counter ), cpu );
1209
+ if (s2 != ad -> id )
1210
+ continue ;
1211
+ if (first )
1212
+ ad -> nr ++ ;
1213
+ counts = perf_counts (counter -> counts , cpu , 0 );
1214
+ ad -> val += counts -> val ;
1215
+ ad -> ena += counts -> ena ;
1216
+ ad -> run += counts -> run ;
1217
+ }
1218
+ }
1219
+
1185
1220
static void print_aggr (char * prefix )
1186
1221
{
1187
1222
FILE * output = stat_config .output ;
1188
1223
struct perf_evsel * counter ;
1189
- int cpu , s , s2 , id , nr ;
1224
+ int s , id , nr ;
1190
1225
double uval ;
1191
1226
u64 ena , run , val ;
1192
1227
bool first ;
@@ -1201,23 +1236,20 @@ static void print_aggr(char *prefix)
1201
1236
* Without each counter has its own line.
1202
1237
*/
1203
1238
for (s = 0 ; s < aggr_map -> nr ; s ++ ) {
1239
+ struct aggr_data ad ;
1204
1240
if (prefix && metric_only )
1205
1241
fprintf (output , "%s" , prefix );
1206
1242
1207
- id = aggr_map -> map [s ];
1243
+ ad . id = id = aggr_map -> map [s ];
1208
1244
first = true;
1209
1245
evlist__for_each_entry (evsel_list , counter ) {
1210
- val = ena = run = 0 ;
1211
- nr = 0 ;
1212
- for (cpu = 0 ; cpu < perf_evsel__nr_cpus (counter ); cpu ++ ) {
1213
- s2 = aggr_get_id (perf_evsel__cpus (counter ), cpu );
1214
- if (s2 != id )
1215
- continue ;
1216
- val += perf_counts (counter -> counts , cpu , 0 )-> val ;
1217
- ena += perf_counts (counter -> counts , cpu , 0 )-> ena ;
1218
- run += perf_counts (counter -> counts , cpu , 0 )-> run ;
1219
- nr ++ ;
1220
- }
1246
+ ad .val = ad .ena = ad .run = 0 ;
1247
+ ad .nr = 0 ;
1248
+ collect_data (counter , aggr_cb , & ad );
1249
+ nr = ad .nr ;
1250
+ ena = ad .ena ;
1251
+ run = ad .run ;
1252
+ val = ad .val ;
1221
1253
if (first && metric_only ) {
1222
1254
first = false;
1223
1255
aggr_printout (counter , id , nr );
@@ -1261,30 +1293,52 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
1261
1293
}
1262
1294
}
1263
1295
1296
+ struct caggr_data {
1297
+ double avg , avg_enabled , avg_running ;
1298
+ };
1299
+
1300
+ static void counter_aggr_cb (struct perf_evsel * counter , void * data ,
1301
+ bool first __maybe_unused )
1302
+ {
1303
+ struct caggr_data * cd = data ;
1304
+ struct perf_stat_evsel * ps = counter -> priv ;
1305
+
1306
+ cd -> avg += avg_stats (& ps -> res_stats [0 ]);
1307
+ cd -> avg_enabled += avg_stats (& ps -> res_stats [1 ]);
1308
+ cd -> avg_running += avg_stats (& ps -> res_stats [2 ]);
1309
+ }
1310
+
1264
1311
/*
1265
1312
* Print out the results of a single counter:
1266
1313
* aggregated counts in system-wide mode
1267
1314
*/
1268
1315
static void print_counter_aggr (struct perf_evsel * counter , char * prefix )
1269
1316
{
1270
1317
FILE * output = stat_config .output ;
1271
- struct perf_stat_evsel * ps = counter -> priv ;
1272
- double avg = avg_stats (& ps -> res_stats [0 ]);
1273
1318
double uval ;
1274
- double avg_enabled , avg_running ;
1319
+ struct caggr_data cd = { . avg = 0.0 } ;
1275
1320
1276
- avg_enabled = avg_stats (& ps -> res_stats [1 ]);
1277
- avg_running = avg_stats (& ps -> res_stats [2 ]);
1321
+ collect_data (counter , counter_aggr_cb , & cd );
1278
1322
1279
1323
if (prefix && !metric_only )
1280
1324
fprintf (output , "%s" , prefix );
1281
1325
1282
- uval = avg * counter -> scale ;
1283
- printout (-1 , 0 , counter , uval , prefix , avg_running , avg_enabled , avg );
1326
+ uval = cd . avg * counter -> scale ;
1327
+ printout (-1 , 0 , counter , uval , prefix , cd . avg_running , cd . avg_enabled , cd . avg );
1284
1328
if (!metric_only )
1285
1329
fprintf (output , "\n" );
1286
1330
}
1287
1331
1332
+ static void counter_cb (struct perf_evsel * counter , void * data ,
1333
+ bool first __maybe_unused )
1334
+ {
1335
+ struct aggr_data * ad = data ;
1336
+
1337
+ ad -> val += perf_counts (counter -> counts , ad -> cpu , 0 )-> val ;
1338
+ ad -> ena += perf_counts (counter -> counts , ad -> cpu , 0 )-> ena ;
1339
+ ad -> run += perf_counts (counter -> counts , ad -> cpu , 0 )-> run ;
1340
+ }
1341
+
1288
1342
/*
1289
1343
* Print out the results of a single counter:
1290
1344
* does not use aggregated count in system-wide
@@ -1297,9 +1351,12 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
1297
1351
int cpu ;
1298
1352
1299
1353
for (cpu = 0 ; cpu < perf_evsel__nr_cpus (counter ); cpu ++ ) {
1300
- val = perf_counts (counter -> counts , cpu , 0 )-> val ;
1301
- ena = perf_counts (counter -> counts , cpu , 0 )-> ena ;
1302
- run = perf_counts (counter -> counts , cpu , 0 )-> run ;
1354
+ struct aggr_data ad = { .cpu = cpu };
1355
+
1356
+ collect_data (counter , counter_cb , & ad );
1357
+ val = ad .val ;
1358
+ ena = ad .ena ;
1359
+ run = ad .run ;
1303
1360
1304
1361
if (prefix )
1305
1362
fprintf (output , "%s" , prefix );
0 commit comments