Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
> so this ^^^ gets removed by > perf, tools: Query terminal width and use in perf list > > please move that patch ahead of this one This cannot be done. There is no code to consume the column width before the other patch. -Andi -- a...@linux.intel.com -- Speaking for myself only. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
so this ^^^ gets removed by perf, tools: Query terminal width and use in perf list please move that patch ahead of this one This cannot be done. There is no code to consume the column width before the other patch. -Andi -- a...@linux.intel.com -- Speaking for myself only. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
On Fri, Jun 27, 2014 at 04:15:57PM -0700, Andi Kleen wrote: > From: Andi Kleen > > Change pmu.c to allow descriptions of events and add interfaces > to add aliases at runtime from another file. To be used by jevents in the > next patch. > > Acked-by: Namhyung Kim > Signed-off-by: Andi Kleen SNIP > + return __perf_pmu__new_alias(list, name, dir, NULL, buf); > +} > + > /* > * Process all the sysfs attributes located under the directory > * specified in 'dir' parameter. > @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct > perf_pmu *pmu, > return buf; > } changes below, the list command update should be separated patch jirka > > -static int cmp_string(const void *a, const void *b) > +struct pair { > + char *name; > + char *desc; > +}; > + > +static int cmp_pair(const void *a, const void *b) > +{ > + const struct pair *as = a; > + const struct pair *bs = b; > + > + /* Put downloaded event list last */ > + if (!!as->desc != !!bs->desc) > + return !!as->desc - !!bs->desc; > + return strcmp(as->name, bs->name); > +} > + > +static void wordwrap(char *s, int start, int max, int corr) > { > - const char * const *as = a; > - const char * const *bs = b; > - return strcmp(*as, *bs); > + int column = start; > + int n; > + > + while (*s) { > + int wlen = strcspn(s, " \t"); > + > + if (column + wlen >= max && column > start) { > + printf("\n%*s", start, ""); > + column = start + corr; > + } > + n = printf("%s%.*s", column > start ? " " : "", wlen, s); > + if (n <= 0) > + break; > + s += wlen; > + column += n; > + while (isspace(*s)) > + s++; > + } > +} > + > +static int get_columns(void) > +{ > + /* > + * Should ask the terminal with TIOCGWINSZ here, but we > + * need the original fd before the pager. > + */ > + return 79; > } > > void print_pmu_events(const char *event_glob, bool name_only) > @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool > name_only) > char buf[1024]; > int printed = 0; > int len, j; > - char **aliases; > + struct pair *aliases; > + int numdesc = 0; > + int columns = get_columns(); > > pmu = NULL; > len = 0; > while ((pmu = perf_pmu__scan(pmu)) != NULL) > list_for_each_entry(alias, >aliases, list) > len++; > - aliases = malloc(sizeof(char *) * len); > + aliases = malloc(sizeof(struct pair) * len); > if (!aliases) > return; > pmu = NULL; > j = 0; > while ((pmu = perf_pmu__scan(pmu)) != NULL) > list_for_each_entry(alias, >aliases, list) { > - char *name = format_alias(buf, sizeof(buf), pmu, alias); > + char *name = alias->desc ? alias->name : > + format_alias(buf, sizeof(buf), pmu, alias); > bool is_cpu = !strcmp(pmu->name, "cpu"); > > if (event_glob != NULL && > @@ -756,22 +816,31 @@ void print_pmu_events(const char *event_glob, bool > name_only) > (!is_cpu && strglobmatch(alias->name, > event_glob > continue; > - aliases[j] = name; > - if (is_cpu && !name_only) > - aliases[j] = format_alias_or(buf, sizeof(buf), > - pmu, alias); > - aliases[j] = strdup(aliases[j]); > + aliases[j].name = name; > + if (is_cpu && !name_only && !alias->desc) > + aliases[j].name = format_alias_or(buf, > + sizeof(buf), > + pmu, alias); > + aliases[j].name = strdup(aliases[j].name); > + aliases[j].desc = alias->desc; > j++; > } > len = j; > - qsort(aliases, len, sizeof(char *), cmp_string); > + qsort(aliases, len, sizeof(struct pair), cmp_pair); > for (j = 0; j < len; j++) { > if (name_only) { > - printf("%s ", aliases[j]); > + printf("%s ", aliases[j].name); > continue; > } > - printf(" %-50s [Kernel PMU event]\n", aliases[j]); > - zfree([j]); > + if (aliases[j].desc) { > + if (numdesc++ == 0 && printed) > + printf("\n"); > + printf(" %-50s [", aliases[j].name); > +
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
On Fri, Jun 27, 2014 at 04:15:57PM -0700, Andi Kleen wrote: > From: Andi Kleen > > Change pmu.c to allow descriptions of events and add interfaces > to add aliases at runtime from another file. To be used by jevents in the > next patch. > > Acked-by: Namhyung Kim > Signed-off-by: Andi Kleen > --- SNIP > +} > + > +static int get_columns(void) > +{ > + /* > + * Should ask the terminal with TIOCGWINSZ here, but we > + * need the original fd before the pager. > + */ > + return 79; > } so this ^^^ gets removed by perf, tools: Query terminal width and use in perf list please move that patch ahead of this one jirka -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
On Fri, Jun 27, 2014 at 04:15:57PM -0700, Andi Kleen wrote: From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases at runtime from another file. To be used by jevents in the next patch. Acked-by: Namhyung Kim namhy...@kernel.org Signed-off-by: Andi Kleen a...@linux.intel.com SNIP + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } changes below, the list command update should be separated patch jirka -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as-desc != !!bs-desc) + return !!as-desc - !!bs-desc; + return strcmp(as-name, bs-name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, \t); + + if (column + wlen = max column start) { + printf(\n%*s, start, ); + column = start + corr; + } + n = printf(%s%.*s, column start ? : , wlen, s); + if (n = 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* + * Should ask the terminal with TIOCGWINSZ here, but we + * need the original fd before the pager. + */ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) { - char *name = format_alias(buf, sizeof(buf), pmu, alias); + char *name = alias-desc ? alias-name : + format_alias(buf, sizeof(buf), pmu, alias); bool is_cpu = !strcmp(pmu-name, cpu); if (event_glob != NULL @@ -756,22 +816,31 @@ void print_pmu_events(const char *event_glob, bool name_only) (!is_cpu strglobmatch(alias-name, event_glob continue; - aliases[j] = name; - if (is_cpu !name_only) - aliases[j] = format_alias_or(buf, sizeof(buf), - pmu, alias); - aliases[j] = strdup(aliases[j]); + aliases[j].name = name; + if (is_cpu !name_only !alias-desc) + aliases[j].name = format_alias_or(buf, + sizeof(buf), + pmu, alias); + aliases[j].name = strdup(aliases[j].name); + aliases[j].desc = alias-desc; j++; } len = j; - qsort(aliases, len, sizeof(char *), cmp_string); + qsort(aliases, len, sizeof(struct pair), cmp_pair); for (j = 0; j len; j++) { if (name_only) { - printf(%s , aliases[j]); + printf(%s , aliases[j].name); continue; } - printf( %-50s [Kernel PMU event]\n, aliases[j]); - zfree(aliases[j]); + if (aliases[j].desc) { + if (numdesc++ == 0 printed) + printf(\n); + printf( %-50s [, aliases[j].name); + wordwrap(aliases[j].desc, 53, columns, 1); + printf(]\n); + } else +
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
On Fri, Jun 27, 2014 at 04:15:57PM -0700, Andi Kleen wrote: From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases at runtime from another file. To be used by jevents in the next patch. Acked-by: Namhyung Kim namhy...@kernel.org Signed-off-by: Andi Kleen a...@linux.intel.com --- SNIP +} + +static int get_columns(void) +{ + /* + * Should ask the terminal with TIOCGWINSZ here, but we + * need the original fd before the pager. + */ + return 79; } so this ^^^ gets removed by perf, tools: Query terminal width and use in perf list please move that patch ahead of this one jirka -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen Change pmu.c to allow descriptions of events and add interfaces to add aliases at runtime from another file. To be used by jevents in the next patch. Acked-by: Namhyung Kim Signed-off-by: Andi Kleen --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias->scale = 1.0; alias->unit[0] = '\0'; - ret = parse_events_terms(>terms, buf); + ret = parse_events_terms(>terms, val); if (ret) { + pr_err("Cannot parse alias %s: %d\n", val, ret); free(alias); return ret; } alias->name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias->desc = desc ? strdup(desc) : NULL; list_add_tail(>list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as->desc != !!bs->desc) + return !!as->desc - !!bs->desc; + return strcmp(as->name, bs->name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL)
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases at runtime from another file. To be used by jevents in the next patch. Acked-by: Namhyung Kim namhy...@kernel.org Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias-scale = 1.0; alias-unit[0] = '\0'; - ret = parse_events_terms(alias-terms, buf); + ret = parse_events_terms(alias-terms, val); if (ret) { + pr_err(Cannot parse alias %s: %d\n, val, ret); free(alias); return ret; } alias-name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias-desc = desc ? strdup(desc) : NULL; list_add_tail(alias-list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as-desc != !!bs-desc) + return !!as-desc - !!bs-desc; + return strcmp(as-name, bs-name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, \t); + + if (column + wlen = max column start) { + printf(\n%*s, start, ); + column = start + corr; + } + n = printf(%s%.*s, column start ? : , wlen, s); + if (n = 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu =
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen Change pmu.c to allow descriptions of events and add interfaces to add aliases at runtime from another file. To be used by jevents in the next patch. Acked-by: Namhyung Kim Signed-off-by: Andi Kleen --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias->scale = 1.0; alias->unit[0] = '\0'; - ret = parse_events_terms(>terms, buf); + ret = parse_events_terms(>terms, val); if (ret) { + pr_err("Cannot parse alias %s: %d\n", val, ret); free(alias); return ret; } alias->name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias->desc = desc ? strdup(desc) : NULL; list_add_tail(>list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as->desc != !!bs->desc) + return !!as->desc - !!bs->desc; + return strcmp(as->name, bs->name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL)
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases at runtime from another file. To be used by jevents in the next patch. Acked-by: Namhyung Kim namhy...@kernel.org Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias-scale = 1.0; alias-unit[0] = '\0'; - ret = parse_events_terms(alias-terms, buf); + ret = parse_events_terms(alias-terms, val); if (ret) { + pr_err(Cannot parse alias %s: %d\n, val, ret); free(alias); return ret; } alias-name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias-desc = desc ? strdup(desc) : NULL; list_add_tail(alias-list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as-desc != !!bs-desc) + return !!as-desc - !!bs-desc; + return strcmp(as-name, bs-name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, \t); + + if (column + wlen = max column start) { + printf(\n%*s, start, ); + column = start + corr; + } + n = printf(%s%.*s, column start ? : , wlen, s); + if (n = 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu =
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
Hi Andi, On Mon, 9 Jun 2014 18:52:45 +0200, Andi Kleen wrote: >> Hmm.. this will print the description at right side and I think it'd be >> better if it prints in another line(s) like below: > > I think it's better to show the descriptions by default without > an extra option. I suspect most people want to see them, or if they > need them they won't know about obscure -v options. I partially agree, but I guess adding -v option to the command is not that hard for them. :) Maybe we could add a message in order to advise users to use -v option for description like below: $ perf list # Use -v/--verbose to see event description (if exists) ... > >> >> agu_bypass_cancel.count[Kernel PMU event] >> This event counts executed load operations with all the following >> traits: 1. addressing of the format [base + offset], 2. the offset >> is between 1 and 2047, 3. the address specified in the base register >> is in one page and the address [base+offset] is in an > > The problem with this format is that it is not compatible, so it would > break existing parsers that look at perf list output. That is why I ended up > with the right side format. Hmm.. I think existing parsers should not use -v option then. The perf list was for listing only event names (and their types). I think the main problem of the right side format is that it hurts readability especially on small screens/terminals. Thanks, Namhyung > > >> arith.fpu_div [Kernel PMU event] >> Divide operations executed >> arith.fpu_div_active [Kernel PMU event] >> Cycles when divider is busy executing divide operations >> ... >> >> >> I just tweaked it using -v option for perf list. Below is the change I >> made on top of your series. What do you think? > > I prefer not to apply that patch. > > I guess what could make sense is a quiet option to not print > descriptions. > > -Andi -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
> Hmm.. this will print the description at right side and I think it'd be > better if it prints in another line(s) like below: I think it's better to show the descriptions by default without an extra option. I suspect most people want to see them, or if they need them they won't know about obscure -v options. > > agu_bypass_cancel.count[Kernel PMU event] > This event counts executed load operations with all the following > traits: 1. addressing of the format [base + offset], 2. the offset > is between 1 and 2047, 3. the address specified in the base register > is in one page and the address [base+offset] is in an The problem with this format is that it is not compatible, so it would break existing parsers that look at perf list output. That is why I ended up with the right side format. > arith.fpu_div [Kernel PMU event] > Divide operations executed > arith.fpu_div_active [Kernel PMU event] > Cycles when divider is busy executing divide operations > ... > > > I just tweaked it using -v option for perf list. Below is the change I > made on top of your series. What do you think? I prefer not to apply that patch. I guess what could make sense is a quiet option to not print descriptions. -Andi -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
Hmm.. this will print the description at right side and I think it'd be better if it prints in another line(s) like below: I think it's better to show the descriptions by default without an extra option. I suspect most people want to see them, or if they need them they won't know about obscure -v options. agu_bypass_cancel.count[Kernel PMU event] This event counts executed load operations with all the following traits: 1. addressing of the format [base + offset], 2. the offset is between 1 and 2047, 3. the address specified in the base register is in one page and the address [base+offset] is in an The problem with this format is that it is not compatible, so it would break existing parsers that look at perf list output. That is why I ended up with the right side format. arith.fpu_div [Kernel PMU event] Divide operations executed arith.fpu_div_active [Kernel PMU event] Cycles when divider is busy executing divide operations ... I just tweaked it using -v option for perf list. Below is the change I made on top of your series. What do you think? I prefer not to apply that patch. I guess what could make sense is a quiet option to not print descriptions. -Andi -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
Hi Andi, On Mon, 9 Jun 2014 18:52:45 +0200, Andi Kleen wrote: Hmm.. this will print the description at right side and I think it'd be better if it prints in another line(s) like below: I think it's better to show the descriptions by default without an extra option. I suspect most people want to see them, or if they need them they won't know about obscure -v options. I partially agree, but I guess adding -v option to the command is not that hard for them. :) Maybe we could add a message in order to advise users to use -v option for description like below: $ perf list # Use -v/--verbose to see event description (if exists) ... agu_bypass_cancel.count[Kernel PMU event] This event counts executed load operations with all the following traits: 1. addressing of the format [base + offset], 2. the offset is between 1 and 2047, 3. the address specified in the base register is in one page and the address [base+offset] is in an The problem with this format is that it is not compatible, so it would break existing parsers that look at perf list output. That is why I ended up with the right side format. Hmm.. I think existing parsers should not use -v option then. The perf list was for listing only event names (and their types). I think the main problem of the right side format is that it hurts readability especially on small screens/terminals. Thanks, Namhyung arith.fpu_div [Kernel PMU event] Divide operations executed arith.fpu_div_active [Kernel PMU event] Cycles when divider is busy executing divide operations ... I just tweaked it using -v option for perf list. Below is the change I made on top of your series. What do you think? I prefer not to apply that patch. I guess what could make sense is a quiet option to not print descriptions. -Andi -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
Hi Andi, On Fri, 30 May 2014 14:50:08 -0700, Andi Kleen wrote: > @@ -756,22 +816,31 @@ void print_pmu_events(const char *event_glob, bool > name_only) > (!is_cpu && strglobmatch(alias->name, > event_glob > continue; > - aliases[j] = name; > - if (is_cpu && !name_only) > - aliases[j] = format_alias_or(buf, sizeof(buf), > - pmu, alias); > - aliases[j] = strdup(aliases[j]); > + aliases[j].name = name; > + if (is_cpu && !name_only && !alias->desc) > + aliases[j].name = format_alias_or(buf, > + sizeof(buf), > + pmu, alias); > + aliases[j].name = strdup(aliases[j].name); > + aliases[j].desc = alias->desc; > j++; > } > len = j; > - qsort(aliases, len, sizeof(char *), cmp_string); > + qsort(aliases, len, sizeof(struct pair), cmp_pair); > for (j = 0; j < len; j++) { > if (name_only) { > - printf("%s ", aliases[j]); > + printf("%s ", aliases[j].name); > continue; > } > - printf(" %-50s [Kernel PMU event]\n", aliases[j]); > - zfree([j]); > + if (aliases[j].desc) { > + if (numdesc++ == 0 && printed) > + printf("\n"); > + printf(" %-50s [", aliases[j].name); > + wordwrap(aliases[j].desc, 53, columns, 1); > + printf("]\n"); > + } else > + printf(" %-50s [Kernel PMU event]\n", aliases[j].name); > + zfree([j].name); Hmm.. this will print the description at right side and I think it'd be better if it prints in another line(s) like below: agu_bypass_cancel.count[Kernel PMU event] This event counts executed load operations with all the following traits: 1. addressing of the format [base + offset], 2. the offset is between 1 and 2047, 3. the address specified in the base register is in one page and the address [base+offset] is in an arith.fpu_div [Kernel PMU event] Divide operations executed arith.fpu_div_active [Kernel PMU event] Cycles when divider is busy executing divide operations ... I just tweaked it using -v option for perf list. Below is the change I made on top of your series. What do you think? Thanks, Namhyung diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 086c96fa959b..e65a3b428a44 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -13,6 +13,7 @@ #include "util/parse-events.h" #include "util/cache.h" +#include "util/debug.h" #include "util/pmu.h" #include "util/parse-options.h" @@ -22,6 +23,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) const struct option list_options[] = { OPT_STRING(0, "events-file", _file, "json file", "Read event json file"), + OPT_INCR('v', "verbose", , +"be more verbose (show event description if exist)"), OPT_END() }; const char * const list_usage[] = { diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b87f52058bb4..99a2156e6c54 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -838,14 +838,16 @@ void print_pmu_events(const char *event_glob, bool name_only) printf("%s ", aliases[j].name); continue; } - if (aliases[j].desc) { - if (numdesc++ == 0 && printed) - printf("\n"); - printf(" %-50s [", aliases[j].name); - wordwrap(aliases[j].desc, 53, columns, 1); - printf("]\n"); - } else - printf(" %-50s [Kernel PMU event]\n", aliases[j].name); + + if (aliases[j].desc && numdesc++ == 0 && printed) + printf("\n"); + printf(" %-50s [Kernel PMU event]\n", aliases[j].name); + + if (aliases[j].desc && verbose) { + printf("%8s", ""); + wordwrap(aliases[j].desc, 8, columns, 1); + printf("\n"); + } zfree([j].name); printed++; } -- To unsubscribe from this list: send the
Re: [PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
Hi Andi, On Fri, 30 May 2014 14:50:08 -0700, Andi Kleen wrote: @@ -756,22 +816,31 @@ void print_pmu_events(const char *event_glob, bool name_only) (!is_cpu strglobmatch(alias-name, event_glob continue; - aliases[j] = name; - if (is_cpu !name_only) - aliases[j] = format_alias_or(buf, sizeof(buf), - pmu, alias); - aliases[j] = strdup(aliases[j]); + aliases[j].name = name; + if (is_cpu !name_only !alias-desc) + aliases[j].name = format_alias_or(buf, + sizeof(buf), + pmu, alias); + aliases[j].name = strdup(aliases[j].name); + aliases[j].desc = alias-desc; j++; } len = j; - qsort(aliases, len, sizeof(char *), cmp_string); + qsort(aliases, len, sizeof(struct pair), cmp_pair); for (j = 0; j len; j++) { if (name_only) { - printf(%s , aliases[j]); + printf(%s , aliases[j].name); continue; } - printf( %-50s [Kernel PMU event]\n, aliases[j]); - zfree(aliases[j]); + if (aliases[j].desc) { + if (numdesc++ == 0 printed) + printf(\n); + printf( %-50s [, aliases[j].name); + wordwrap(aliases[j].desc, 53, columns, 1); + printf(]\n); + } else + printf( %-50s [Kernel PMU event]\n, aliases[j].name); + zfree(aliases[j].name); Hmm.. this will print the description at right side and I think it'd be better if it prints in another line(s) like below: agu_bypass_cancel.count[Kernel PMU event] This event counts executed load operations with all the following traits: 1. addressing of the format [base + offset], 2. the offset is between 1 and 2047, 3. the address specified in the base register is in one page and the address [base+offset] is in an arith.fpu_div [Kernel PMU event] Divide operations executed arith.fpu_div_active [Kernel PMU event] Cycles when divider is busy executing divide operations ... I just tweaked it using -v option for perf list. Below is the change I made on top of your series. What do you think? Thanks, Namhyung diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 086c96fa959b..e65a3b428a44 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -13,6 +13,7 @@ #include util/parse-events.h #include util/cache.h +#include util/debug.h #include util/pmu.h #include util/parse-options.h @@ -22,6 +23,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) const struct option list_options[] = { OPT_STRING(0, events-file, json_file, json file, Read event json file), + OPT_INCR('v', verbose, verbose, +be more verbose (show event description if exist)), OPT_END() }; const char * const list_usage[] = { diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b87f52058bb4..99a2156e6c54 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -838,14 +838,16 @@ void print_pmu_events(const char *event_glob, bool name_only) printf(%s , aliases[j].name); continue; } - if (aliases[j].desc) { - if (numdesc++ == 0 printed) - printf(\n); - printf( %-50s [, aliases[j].name); - wordwrap(aliases[j].desc, 53, columns, 1); - printf(]\n); - } else - printf( %-50s [Kernel PMU event]\n, aliases[j].name); + + if (aliases[j].desc numdesc++ == 0 printed) + printf(\n); + printf( %-50s [Kernel PMU event]\n, aliases[j].name); + + if (aliases[j].desc verbose) { + printf(%8s, ); + wordwrap(aliases[j].desc, 8, columns, 1); + printf(\n); + } zfree(aliases[j].name); printed++; } -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen Change pmu.c to allow descriptions of events and add interfaces to add aliases. Used in the next patch. Signed-off-by: Andi Kleen --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias->scale = 1.0; alias->unit[0] = '\0'; - ret = parse_events_terms(>terms, buf); + ret = parse_events_terms(>terms, val); if (ret) { + pr_err("Cannot parse alias %s: %d\n", val, ret); free(alias); return ret; } alias->name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias->desc = desc ? strdup(desc) : NULL; list_add_tail(>list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as->desc != !!bs->desc) + return !!as->desc - !!bs->desc; + return strcmp(as->name, bs->name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) { - char
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases. Used in the next patch. Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias-scale = 1.0; alias-unit[0] = '\0'; - ret = parse_events_terms(alias-terms, buf); + ret = parse_events_terms(alias-terms, val); if (ret) { + pr_err(Cannot parse alias %s: %d\n, val, ret); free(alias); return ret; } alias-name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias-desc = desc ? strdup(desc) : NULL; list_add_tail(alias-list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as-desc != !!bs-desc) + return !!as-desc - !!bs-desc; + return strcmp(as-name, bs-name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, \t); + + if (column + wlen = max column start) { + printf(\n%*s, start, ); + column = start + corr; + } + n = printf(%s%.*s, column start ? : , wlen, s); + if (n = 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list)
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen Change pmu.c to allow descriptions of events and add interfaces to add aliases. Used in the next patch. Signed-off-by: Andi Kleen --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias->scale = 1.0; alias->unit[0] = '\0'; - ret = parse_events_terms(>terms, buf); + ret = parse_events_terms(>terms, val); if (ret) { + pr_err("Cannot parse alias %s: %d\n", val, ret); free(alias); return ret; } alias->name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias->desc = desc ? strdup(desc) : NULL; list_add_tail(>list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as->desc != !!bs->desc) + return !!as->desc - !!bs->desc; + return strcmp(as->name, bs->name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) { - char
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases. Used in the next patch. Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias-scale = 1.0; alias-unit[0] = '\0'; - ret = parse_events_terms(alias-terms, buf); + ret = parse_events_terms(alias-terms, val); if (ret) { + pr_err(Cannot parse alias %s: %d\n, val, ret); free(alias); return ret; } alias-name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias-desc = desc ? strdup(desc) : NULL; list_add_tail(alias-list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as-desc != !!bs-desc) + return !!as-desc - !!bs-desc; + return strcmp(as-name, bs-name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, \t); + + if (column + wlen = max column start) { + printf(\n%*s, start, ); + column = start + corr; + } + n = printf(%s%.*s, column start ? : , wlen, s); + if (n = 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list)
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen Change pmu.c to allow descriptions of events and add interfaces to add aliases. Used in the next patch. Signed-off-by: Andi Kleen --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias->scale = 1.0; alias->unit[0] = '\0'; - ret = parse_events_terms(>terms, buf); + ret = parse_events_terms(>terms, val); if (ret) { + pr_err("Cannot parse alias %s: %d\n", val, ret); free(alias); return ret; } alias->name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias->desc = desc ? strdup(desc) : NULL; list_add_tail(>list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as->desc != !!bs->desc) + return !!as->desc - !!bs->desc; + return strcmp(as->name, bs->name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, >aliases, list) { - char
[PATCH 2/9] perf, tools: Add support for text descriptions of events and alias add
From: Andi Kleen a...@linux.intel.com Change pmu.c to allow descriptions of events and add interfaces to add aliases. Used in the next patch. Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/util/pmu.c | 127 ++ 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb..baec090 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,6 +14,7 @@ struct perf_pmu_alias { char *name; + char *desc; struct list_head terms; struct list_head list; char unit[UNIT_MAX_LEN+1]; @@ -171,17 +172,12 @@ error: return -1; } -static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) +static int __perf_pmu__new_alias(struct list_head *list, char *name, +char *dir, char *desc, char *val) { struct perf_pmu_alias *alias; - char buf[256]; int ret; - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - alias = malloc(sizeof(*alias)); if (!alias) return -ENOMEM; @@ -190,24 +186,45 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI alias-scale = 1.0; alias-unit[0] = '\0'; - ret = parse_events_terms(alias-terms, buf); + ret = parse_events_terms(alias-terms, val); if (ret) { + pr_err(Cannot parse alias %s: %d\n, val, ret); free(alias); return ret; } alias-name = strdup(name); - /* -* load unit name and scale if available -*/ - perf_pmu__parse_unit(alias, dir, name); - perf_pmu__parse_scale(alias, dir, name); + if (dir) { + /* +* load unit name and scale if available +*/ + perf_pmu__parse_unit(alias, dir, name); + perf_pmu__parse_scale(alias, dir, name); + } + + alias-desc = desc ? strdup(desc) : NULL; list_add_tail(alias-list, list); return 0; } +static int perf_pmu__new_alias(struct list_head *list, + char *dir, + char *name, + FILE *file) +{ + char buf[256]; + int ret; + + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + return -EINVAL; + buf[ret] = 0; + + return __perf_pmu__new_alias(list, name, dir, NULL, buf); +} + /* * Process all the sysfs attributes located under the directory * specified in 'dir' parameter. @@ -720,11 +737,51 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, return buf; } -static int cmp_string(const void *a, const void *b) +struct pair { + char *name; + char *desc; +}; + +static int cmp_pair(const void *a, const void *b) +{ + const struct pair *as = a; + const struct pair *bs = b; + + /* Put downloaded event list last */ + if (!!as-desc != !!bs-desc) + return !!as-desc - !!bs-desc; + return strcmp(as-name, bs-name); +} + +static void wordwrap(char *s, int start, int max, int corr) { - const char * const *as = a; - const char * const *bs = b; - return strcmp(*as, *bs); + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, \t); + + if (column + wlen = max column start) { + printf(\n%*s, start, ); + column = start + corr; + } + n = printf(%s%.*s, column start ? : , wlen, s); + if (n = 0) + break; + s += wlen; + column += n; + while (isspace(*s)) + s++; + } +} + +static int get_columns(void) +{ + /* +* Should ask the terminal with TIOCGWINSZ here, but we +* need the original fd before the pager. +*/ + return 79; } void print_pmu_events(const char *event_glob, bool name_only) @@ -734,21 +791,24 @@ void print_pmu_events(const char *event_glob, bool name_only) char buf[1024]; int printed = 0; int len, j; - char **aliases; + struct pair *aliases; + int numdesc = 0; + int columns = get_columns(); pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list) len++; - aliases = malloc(sizeof(char *) * len); + aliases = malloc(sizeof(struct pair) * len); if (!aliases) return; pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) list_for_each_entry(alias, pmu-aliases, list)