[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1423833115-11199-3-git-send-email-yunlong.song@huawei.com>
Date: Fri, 13 Feb 2015 21:11:50 +0800
From: Yunlong Song <yunlong.song@...wei.com>
To: <a.p.zijlstra@...llo.nl>, <paulus@...ba.org>, <mingo@...hat.com>,
<acme@...nel.org>
CC: <linux-kernel@...r.kernel.org>, <wangnan0@...wei.com>
Subject: [PATCH 2/7] 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@...wei.com>
---
tools/perf/builtin-list.c | 2 -
tools/perf/util/parse-events.c | 166 +++++++++++++++++++++++++++++++++++------
2 files changed, 145 insertions(+), 23 deletions(-)
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 051a163..de5680e 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -47,8 +47,6 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
}
for (i = 0; i < argc; ++i) {
- if (i)
- putchar('\n');
if (strncmp(argv[i], "tracepoint", 10) == 0)
print_tracepoint_events(NULL, NULL, false);
else if (strcmp(argv[i], "hw") == 0 ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index fa876da..cf35b0a 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1093,6 +1093,13 @@ static const char * const event_type_descriptors[] = {
"Hardware breakpoint",
};
+static int cmp_string(const void *a, const void *b)
+{
+ const char * const *as = a;
+ const char * const *bs = b;
+ return strcmp(*as, *bs);
+}
+
/*
* Print the events from <debugfs_mount_point>/tracing/events
*/
@@ -1105,6 +1112,9 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
char evt_path[MAXPATHLEN];
char dir_path[MAXPATHLEN];
char sbuf[STRERR_BUFSIZE];
+ char **evt_list = NULL;
+ unsigned int evt_i = 0, evt_num = 0;
+ bool evt_num_known = false;
if (debugfs_valid_mountpoint(tracing_events_path)) {
printf(" [ Tracepoints not available: %s ]\n",
@@ -1112,9 +1122,16 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
return;
}
+restart:
sys_dir = opendir(tracing_events_path);
if (!sys_dir)
return;
+
+ if (evt_num_known) {
+ evt_list = zalloc(sizeof(char *) * evt_num);
+ if (!evt_list)
+ goto out_enomem;
+ }
for_each_subsystem(sys_dir, sys_dirent, sys_next) {
if (subsys_glob != NULL &&
@@ -1132,19 +1149,52 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
!strglobmatch(evt_dirent.d_name, event_glob))
continue;
- if (name_only) {
- printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
+ if (!evt_num_known) {
+ evt_num++;
continue;
}
snprintf(evt_path, MAXPATHLEN, "%s:%s",
sys_dirent.d_name, evt_dirent.d_name);
- printf(" %-50s [%s]\n", evt_path,
- event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+
+ evt_list[evt_i] = strdup(evt_path);
+ if (evt_list[evt_i] == NULL)
+ goto out_enomem;
+ evt_i++;
}
closedir(evt_dir);
}
closedir(sys_dir);
+
+ if (!evt_num_known) {
+ evt_num_known = true;
+ goto restart;
+ }
+ qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+ evt_i = 0;
+ while (evt_i < evt_num) {
+ if (name_only) {
+ printf("%s ", evt_list[evt_i++]);
+ continue;
+ }
+ printf(" %-50s [%s]\n", evt_list[evt_i++],
+ event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+ }
+ if (evt_num)
+ printf("\n");
+
+out_free:
+ evt_num = evt_i;
+ for (evt_i = 0; evt_i < evt_num; evt_i++)
+ zfree(&evt_list[evt_i]);
+ zfree(&evt_list);
+ return;
+
+out_enomem:
+ printf("FATAL: not enough memory to print %s\n",
+ event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+ if (evt_list)
+ goto out_free;
}
/*
@@ -1230,8 +1280,17 @@ static bool is_event_supported(u8 type, unsigned config)
int print_hwcache_events(const char *event_glob, bool name_only)
{
- unsigned int type, op, i, printed = 0;
+ unsigned int type, op, i, evt_i = 0, evt_num = 0;
char name[64];
+ char **evt_list = NULL;
+ bool evt_num_known = false;
+
+restart:
+ if (evt_num_known) {
+ evt_list = zalloc(sizeof(char *) * evt_num);
+ if (!evt_list)
+ goto out_enomem;
+ }
for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
@@ -1249,27 +1308,66 @@ int print_hwcache_events(const char *event_glob, bool name_only)
type | (op << 8) | (i << 16)))
continue;
- if (name_only)
- printf("%s ", name);
- else
- printf(" %-50s [%s]\n", name,
- event_type_descriptors[PERF_TYPE_HW_CACHE]);
- ++printed;
+ if (!evt_num_known) {
+ evt_num++;
+ continue;
+ }
+
+ evt_list[evt_i] = strdup(name);
+ if (evt_list[evt_i] == NULL)
+ goto out_enomem;
+ evt_i++;
}
}
}
- if (printed)
+ if (!evt_num_known) {
+ evt_num_known = true;
+ goto restart;
+ }
+ qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+ evt_i = 0;
+ while (evt_i < evt_num) {
+ if (name_only) {
+ printf("%s ", evt_list[evt_i++]);
+ continue;
+ }
+ printf(" %-50s [%s]\n", evt_list[evt_i++],
+ event_type_descriptors[PERF_TYPE_HW_CACHE]);
+ }
+ if (evt_num)
printf("\n");
- return printed;
+
+out_free:
+ evt_num = evt_i;
+ for (evt_i = 0; evt_i < evt_num; evt_i++)
+ zfree(&evt_list[evt_i]);
+ zfree(&evt_list);
+ return evt_num;
+
+out_enomem:
+ printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]);
+ if (evt_list)
+ goto out_free;
+ return evt_num;
}
void print_symbol_events(const char *event_glob, unsigned type,
struct event_symbol *syms, unsigned max,
bool name_only)
{
- unsigned i, printed = 0;
+ unsigned int i, evt_i = 0, evt_num = 0;
char name[MAX_NAME_LEN];
+ char **evt_list = NULL;
+ bool evt_num_known = false;
+
+restart:
+ if (evt_num_known) {
+ evt_list = zalloc(sizeof(char *) * evt_num);
+ if (!evt_list)
+ goto out_enomem;
+ syms -= max;
+ }
for (i = 0; i < max; i++, syms++) {
@@ -1281,23 +1379,49 @@ void print_symbol_events(const char *event_glob, unsigned type,
if (!is_event_supported(type, i))
continue;
- if (name_only) {
- printf("%s ", syms->symbol);
+ if (!evt_num_known) {
+ evt_num++;
continue;
}
- if (strlen(syms->alias))
+ if (!name_only && strlen(syms->alias))
snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
else
strncpy(name, syms->symbol, MAX_NAME_LEN);
- printf(" %-50s [%s]\n", name, event_type_descriptors[type]);
-
- printed++;
+ evt_list[evt_i] = strdup(name);
+ if (evt_list[evt_i] == NULL)
+ goto out_enomem;
+ evt_i++;
}
- if (printed)
+ if (!evt_num_known) {
+ evt_num_known = true;
+ goto restart;
+ }
+ qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+ evt_i = 0;
+ while (evt_i < evt_num) {
+ if (name_only) {
+ printf("%s ", evt_list[evt_i++]);
+ continue;
+ }
+ printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
+ }
+ if (evt_num)
printf("\n");
+
+out_free:
+ evt_num = evt_i;
+ for (evt_i = 0; evt_i < evt_num; evt_i++)
+ zfree(&evt_list[evt_i]);
+ zfree(&evt_list);
+ return;
+
+out_enomem:
+ printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
+ if (evt_list)
+ goto out_free;
}
/*
--
1.8.5.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists