aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorYunlong Song <yunlong.song@huawei.com>2015-02-27 05:21:25 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-02-27 13:51:44 -0500
commitab0e48002db818c1937f105cd18001dfdd3ce056 (patch)
tree9388426be1d155683d1b386adfa43ef552b4a9f1 /tools
parent1f924c29b5ab2257be88a2a4075d0800573d8479 (diff)
perf list: Sort the output of 'perf list' to view more clearly
Sort the output according to ASCII character list (using strcmp), which supports both number sequence and alphabet sequence. Example: Before this patch: $ perf list List of pre-defined events (to be used in -e): cpu-cycles OR cycles [Hardware event] instructions [Hardware event] cache-references [Hardware event] cache-misses [Hardware event] branch-instructions OR branches [Hardware event] branch-misses [Hardware event] bus-cycles [Hardware event] ... ... jbd2:jbd2_start_commit [Tracepoint event] jbd2:jbd2_commit_locking [Tracepoint event] jbd2:jbd2_run_stats [Tracepoint event] block:block_rq_issue [Tracepoint event] block:block_bio_complete [Tracepoint event] block:block_bio_backmerge [Tracepoint event] block:block_getrq [Tracepoint event] ... ... After this patch: $ perf list List of pre-defined events (to be used in -e): branch-instructions OR branches [Hardware event] branch-misses [Hardware event] bus-cycles [Hardware event] cache-misses [Hardware event] cache-references [Hardware event] cpu-cycles OR cycles [Hardware event] instructions [Hardware event] ... ... block:block_bio_backmerge [Tracepoint event] block:block_bio_complete [Tracepoint event] block:block_getrq [Tracepoint event] block:block_rq_issue [Tracepoint event] jbd2:jbd2_commit_locking [Tracepoint event] jbd2:jbd2_run_stats [Tracepoint event] jbd2:jbd2_start_commit [Tracepoint event] ... ... Signed-off-by: Yunlong Song <yunlong.song@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/r/1425032491-20224-2-git-send-email-yunlong.song@huawei.com [ Don't forget closedir({sys,evt}_dir) when handling errors ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/parse-events.c216
1 files changed, 193 insertions, 23 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 109ba5c8c2e5..f6822d9b2b53 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1089,6 +1089,14 @@ static const char * const event_type_descriptors[] = {
1089 "Hardware breakpoint", 1089 "Hardware breakpoint",
1090}; 1090};
1091 1091
1092static int cmp_string(const void *a, const void *b)
1093{
1094 const char * const *as = a;
1095 const char * const *bs = b;
1096
1097 return strcmp(*as, *bs);
1098}
1099
1092/* 1100/*
1093 * Print the events from <debugfs_mount_point>/tracing/events 1101 * Print the events from <debugfs_mount_point>/tracing/events
1094 */ 1102 */
@@ -1100,11 +1108,21 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
1100 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1108 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
1101 char evt_path[MAXPATHLEN]; 1109 char evt_path[MAXPATHLEN];
1102 char dir_path[MAXPATHLEN]; 1110 char dir_path[MAXPATHLEN];
1111 char **evt_list = NULL;
1112 unsigned int evt_i = 0, evt_num = 0;
1113 bool evt_num_known = false;
1103 1114
1115restart:
1104 sys_dir = opendir(tracing_events_path); 1116 sys_dir = opendir(tracing_events_path);
1105 if (!sys_dir) 1117 if (!sys_dir)
1106 return; 1118 return;
1107 1119
1120 if (evt_num_known) {
1121 evt_list = zalloc(sizeof(char *) * evt_num);
1122 if (!evt_list)
1123 goto out_close_sys_dir;
1124 }
1125
1108 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1126 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
1109 if (subsys_glob != NULL && 1127 if (subsys_glob != NULL &&
1110 !strglobmatch(sys_dirent.d_name, subsys_glob)) 1128 !strglobmatch(sys_dirent.d_name, subsys_glob))
@@ -1121,19 +1139,56 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
1121 !strglobmatch(evt_dirent.d_name, event_glob)) 1139 !strglobmatch(evt_dirent.d_name, event_glob))
1122 continue; 1140 continue;
1123 1141
1124 if (name_only) { 1142 if (!evt_num_known) {
1125 printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name); 1143 evt_num++;
1126 continue; 1144 continue;
1127 } 1145 }
1128 1146
1129 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1147 snprintf(evt_path, MAXPATHLEN, "%s:%s",
1130 sys_dirent.d_name, evt_dirent.d_name); 1148 sys_dirent.d_name, evt_dirent.d_name);
1131 printf(" %-50s [%s]\n", evt_path, 1149
1132 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1150 evt_list[evt_i] = strdup(evt_path);
1151 if (evt_list[evt_i] == NULL)
1152 goto out_close_evt_dir;
1153 evt_i++;
1133 } 1154 }
1134 closedir(evt_dir); 1155 closedir(evt_dir);
1135 } 1156 }
1136 closedir(sys_dir); 1157 closedir(sys_dir);
1158
1159 if (!evt_num_known) {
1160 evt_num_known = true;
1161 goto restart;
1162 }
1163 qsort(evt_list, evt_num, sizeof(char *), cmp_string);
1164 evt_i = 0;
1165 while (evt_i < evt_num) {
1166 if (name_only) {
1167 printf("%s ", evt_list[evt_i++]);
1168 continue;
1169 }
1170 printf(" %-50s [%s]\n", evt_list[evt_i++],
1171 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
1172 }
1173 if (evt_num)
1174 printf("\n");
1175
1176out_free:
1177 evt_num = evt_i;
1178 for (evt_i = 0; evt_i < evt_num; evt_i++)
1179 zfree(&evt_list[evt_i]);
1180 zfree(&evt_list);
1181 return;
1182
1183out_close_evt_dir:
1184 closedir(evt_dir);
1185out_close_sys_dir:
1186 closedir(sys_dir);
1187
1188 printf("FATAL: not enough memory to print %s\n",
1189 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
1190 if (evt_list)
1191 goto out_free;
1137} 1192}
1138 1193
1139/* 1194/*
@@ -1218,20 +1273,61 @@ static void __print_events_type(u8 type, struct event_symbol *syms,
1218 unsigned max) 1273 unsigned max)
1219{ 1274{
1220 char name[64]; 1275 char name[64];
1221 unsigned i; 1276 unsigned int i, evt_i = 0, evt_num = 0;
1277 char **evt_list = NULL;
1278 bool evt_num_known = false;
1279
1280restart:
1281 if (evt_num_known) {
1282 evt_list = zalloc(sizeof(char *) * evt_num);
1283 if (!evt_list)
1284 goto out_enomem;
1285 syms -= max;
1286 }
1222 1287
1223 for (i = 0; i < max ; i++, syms++) { 1288 for (i = 0; i < max ; i++, syms++) {
1224 if (!is_event_supported(type, i)) 1289 if (!is_event_supported(type, i))
1225 continue; 1290 continue;
1226 1291
1292 if (!evt_num_known) {
1293 evt_num++;
1294 continue;
1295 }
1296
1227 if (strlen(syms->alias)) 1297 if (strlen(syms->alias))
1228 snprintf(name, sizeof(name), "%s OR %s", 1298 snprintf(name, sizeof(name), "%s OR %s",
1229 syms->symbol, syms->alias); 1299 syms->symbol, syms->alias);
1230 else 1300 else
1231 snprintf(name, sizeof(name), "%s", syms->symbol); 1301 snprintf(name, sizeof(name), "%s", syms->symbol);
1232 1302
1233 printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 1303 evt_list[evt_i] = strdup(name);
1304 if (evt_list[evt_i] == NULL)
1305 goto out_enomem;
1306 evt_i++;
1307 }
1308
1309 if (!evt_num_known) {
1310 evt_num_known = true;
1311 goto restart;
1234 } 1312 }
1313 qsort(evt_list, evt_num, sizeof(char *), cmp_string);
1314 evt_i = 0;
1315 while (evt_i < evt_num)
1316 printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
1317 if (evt_num)
1318 printf("\n");
1319
1320out_free:
1321 evt_num = evt_i;
1322 for (evt_i = 0; evt_i < evt_num; evt_i++)
1323 zfree(&evt_list[evt_i]);
1324 zfree(&evt_list);
1325 return;
1326
1327out_enomem:
1328 printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
1329 if (evt_list)
1330 goto out_free;
1235} 1331}
1236 1332
1237void print_events_type(u8 type) 1333void print_events_type(u8 type)
@@ -1244,8 +1340,17 @@ void print_events_type(u8 type)
1244 1340
1245int print_hwcache_events(const char *event_glob, bool name_only) 1341int print_hwcache_events(const char *event_glob, bool name_only)
1246{ 1342{
1247 unsigned int type, op, i, printed = 0; 1343 unsigned int type, op, i, evt_i = 0, evt_num = 0;
1248 char name[64]; 1344 char name[64];
1345 char **evt_list = NULL;
1346 bool evt_num_known = false;
1347
1348restart:
1349 if (evt_num_known) {
1350 evt_list = zalloc(sizeof(char *) * evt_num);
1351 if (!evt_list)
1352 goto out_enomem;
1353 }
1249 1354
1250 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1355 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
1251 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1356 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
@@ -1263,27 +1368,66 @@ int print_hwcache_events(const char *event_glob, bool name_only)
1263 type | (op << 8) | (i << 16))) 1368 type | (op << 8) | (i << 16)))
1264 continue; 1369 continue;
1265 1370
1266 if (name_only) 1371 if (!evt_num_known) {
1267 printf("%s ", name); 1372 evt_num++;
1268 else 1373 continue;
1269 printf(" %-50s [%s]\n", name, 1374 }
1270 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1375
1271 ++printed; 1376 evt_list[evt_i] = strdup(name);
1377 if (evt_list[evt_i] == NULL)
1378 goto out_enomem;
1379 evt_i++;
1272 } 1380 }
1273 } 1381 }
1274 } 1382 }
1275 1383
1276 if (printed) 1384 if (!evt_num_known) {
1385 evt_num_known = true;
1386 goto restart;
1387 }
1388 qsort(evt_list, evt_num, sizeof(char *), cmp_string);
1389 evt_i = 0;
1390 while (evt_i < evt_num) {
1391 if (name_only) {
1392 printf("%s ", evt_list[evt_i++]);
1393 continue;
1394 }
1395 printf(" %-50s [%s]\n", evt_list[evt_i++],
1396 event_type_descriptors[PERF_TYPE_HW_CACHE]);
1397 }
1398 if (evt_num)
1277 printf("\n"); 1399 printf("\n");
1278 return printed; 1400
1401out_free:
1402 evt_num = evt_i;
1403 for (evt_i = 0; evt_i < evt_num; evt_i++)
1404 zfree(&evt_list[evt_i]);
1405 zfree(&evt_list);
1406 return evt_num;
1407
1408out_enomem:
1409 printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]);
1410 if (evt_list)
1411 goto out_free;
1412 return evt_num;
1279} 1413}
1280 1414
1281static void print_symbol_events(const char *event_glob, unsigned type, 1415static void print_symbol_events(const char *event_glob, unsigned type,
1282 struct event_symbol *syms, unsigned max, 1416 struct event_symbol *syms, unsigned max,
1283 bool name_only) 1417 bool name_only)
1284{ 1418{
1285 unsigned i, printed = 0; 1419 unsigned int i, evt_i = 0, evt_num = 0;
1286 char name[MAX_NAME_LEN]; 1420 char name[MAX_NAME_LEN];
1421 char **evt_list = NULL;
1422 bool evt_num_known = false;
1423
1424restart:
1425 if (evt_num_known) {
1426 evt_list = zalloc(sizeof(char *) * evt_num);
1427 if (!evt_list)
1428 goto out_enomem;
1429 syms -= max;
1430 }
1287 1431
1288 for (i = 0; i < max; i++, syms++) { 1432 for (i = 0; i < max; i++, syms++) {
1289 1433
@@ -1295,23 +1439,49 @@ static void print_symbol_events(const char *event_glob, unsigned type,
1295 if (!is_event_supported(type, i)) 1439 if (!is_event_supported(type, i))
1296 continue; 1440 continue;
1297 1441
1298 if (name_only) { 1442 if (!evt_num_known) {
1299 printf("%s ", syms->symbol); 1443 evt_num++;
1300 continue; 1444 continue;
1301 } 1445 }
1302 1446
1303 if (strlen(syms->alias)) 1447 if (!name_only && strlen(syms->alias))
1304 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 1448 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
1305 else 1449 else
1306 strncpy(name, syms->symbol, MAX_NAME_LEN); 1450 strncpy(name, syms->symbol, MAX_NAME_LEN);
1307 1451
1308 printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 1452 evt_list[evt_i] = strdup(name);
1309 1453 if (evt_list[evt_i] == NULL)
1310 printed++; 1454 goto out_enomem;
1455 evt_i++;
1311 } 1456 }
1312 1457
1313 if (printed) 1458 if (!evt_num_known) {
1459 evt_num_known = true;
1460 goto restart;
1461 }
1462 qsort(evt_list, evt_num, sizeof(char *), cmp_string);
1463 evt_i = 0;
1464 while (evt_i < evt_num) {
1465 if (name_only) {
1466 printf("%s ", evt_list[evt_i++]);
1467 continue;
1468 }
1469 printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
1470 }
1471 if (evt_num)
1314 printf("\n"); 1472 printf("\n");
1473
1474out_free:
1475 evt_num = evt_i;
1476 for (evt_i = 0; evt_i < evt_num; evt_i++)
1477 zfree(&evt_list[evt_i]);
1478 zfree(&evt_list);
1479 return;
1480
1481out_enomem:
1482 printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
1483 if (evt_list)
1484 goto out_free;
1315} 1485}
1316 1486
1317/* 1487/*