Re: [PATCH 2/4] perf hist: Simplify hist printing logic for group events

From: Ian Rogers
Date: Wed Feb 14 2024 - 19:02:14 EST


On Mon, Feb 12, 2024 at 11:53 PM Namhyung Kim <namhyung@xxxxxxxxxx> wrote:
>
> It can uses an array to save the period (or percent) values for member
> events and print them together in a loop. This simplify the logic to
> handle missing samples in members with zero values.
>
> No functional change intended.
>
> Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
> ---
> tools/perf/ui/hist.c | 55 +++++++++++++++++---------------------------
> 1 file changed, 21 insertions(+), 34 deletions(-)
>
> diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
> index 2bf959d08354..5f4c110d840f 100644
> --- a/tools/perf/ui/hist.c
> +++ b/tools/perf/ui/hist.c
> @@ -33,6 +33,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> char *buf = hpp->buf;
> size_t size = hpp->size;
>
> + /* print stand-alone or group leader events separately */
> if (fmt_percent) {
> double percent = 0.0;
> u64 total = hists__total_period(hists);
> @@ -45,12 +46,19 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> ret = hpp__call_print_fn(hpp, print_fn, fmt, len, get_field(he));
>
> if (evsel__is_group_event(evsel)) {
> - int prev_idx, idx_delta;
> + int idx;
> struct hist_entry *pair;
> int nr_members = evsel->core.nr_members;
> + union {
> + u64 period;
> + double percent;
> + } *val;
>
> - prev_idx = evsel__group_idx(evsel);
> + val = calloc(nr_members, sizeof(*val));
> + if (val == NULL)
> + return 0;

Looks good, but should this return value be negative to indicate an
error? Snprintf gives a negative result on error, its result is
sometimes returned from hpp__fmt_acc, as is this result.

Thanks,
Ian

>
> + /* collect values in the group members */
> list_for_each_entry(pair, &he->pairs.head, pairs.node) {
> u64 period = get_field(pair);
> u64 total = hists__total_period(pair->hists);
> @@ -59,47 +67,26 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
> continue;
>
> evsel = hists_to_evsel(pair->hists);
> - idx_delta = evsel__group_idx(evsel) - prev_idx - 1;
> -
> - while (idx_delta--) {
> - /*
> - * zero-fill group members in the middle which
> - * have no sample
> - */
> - if (fmt_percent) {
> - ret += hpp__call_print_fn(hpp, print_fn,
> - fmt, len, 0.0);
> - } else {
> - ret += hpp__call_print_fn(hpp, print_fn,
> - fmt, len, 0ULL);
> - }
> - }
> -
> - if (fmt_percent) {
> - ret += hpp__call_print_fn(hpp, print_fn, fmt, len,
> - 100.0 * period / total);
> - } else {
> - ret += hpp__call_print_fn(hpp, print_fn, fmt,
> - len, period);
> - }
> + idx = evsel__group_idx(evsel);
>
> - prev_idx = evsel__group_idx(evsel);
> + if (fmt_percent)
> + val[idx].percent = 100.0 * period / total;
> + else
> + val[idx].period = period;
> }
>
> - idx_delta = nr_members - prev_idx - 1;
> -
> - while (idx_delta--) {
> - /*
> - * zero-fill group members at last which have no sample
> - */
> + /* idx starts from 1 to skip the leader event */
> + for (idx = 1; idx < nr_members; idx++) {
> if (fmt_percent) {
> ret += hpp__call_print_fn(hpp, print_fn,
> - fmt, len, 0.0);
> + fmt, len, val[idx].percent);
> } else {
> ret += hpp__call_print_fn(hpp, print_fn,
> - fmt, len, 0ULL);
> + fmt, len, val[idx].period);
> }
> }
> +
> + free(val);
> }
>
> /*
> --
> 2.43.0.687.g38aa6559b0-goog
>