tools/perf/ui/hist.c

Source file repositories/reference/linux-study-clean/tools/perf/ui/hist.c

File Facts

System
Linux kernel
Corpus path
tools/perf/ui/hist.c
Extension
.c
Size
32335 bytes
Lines
1274
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct hpp_fmt_value {
	struct hists *hists;
	u64 val;
	int samples;
};

static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
		      hpp_field_fn get_field, const char *fmt, int len,
		      hpp_snprint_fn print_fn, enum perf_hpp_fmt_type fmtype)
{
	int ret = 0;
	struct hists *hists = he->hists;
	struct evsel *evsel = hists_to_evsel(hists);
	struct evsel *pos;
	char *buf = hpp->buf;
	size_t size = hpp->size;
	int i = 0, nr_members = 1;
	struct hpp_fmt_value *values;

	if (evsel__is_group_event(evsel))
		nr_members = evsel->core.nr_members;

	values = calloc(nr_members, sizeof(*values));
	if (values == NULL)
		return 0;

	values[0].hists = evsel__hists(evsel);
	values[0].val = get_field(he);
	values[0].samples = he->stat.nr_events;

	if (evsel__is_group_event(evsel)) {
		struct hist_entry *pair;

		for_each_group_member(pos, evsel)
			values[++i].hists = evsel__hists(pos);

		list_for_each_entry(pair, &he->pairs.head, pairs.node) {
			for (i = 0; i < nr_members; i++) {
				if (values[i].hists != pair->hists)
					continue;

				values[i].val = get_field(pair);
				values[i].samples = pair->stat.nr_events;
				break;
			}
		}
	}

	for (i = 0; i < nr_members; i++) {
		if (symbol_conf.skip_empty &&
		    values[i].hists->stats.nr_samples == 0)
			continue;

		ret += __hpp__fmt_print(hpp, values[i].hists, values[i].val,
					values[i].samples, fmt, len,
					print_fn, fmtype);
	}

	free(values);

	/*
	 * Restore original buf and size as it's where caller expects
	 * the result will be saved.
	 */
	hpp->buf = buf;
	hpp->size = size;

	return ret;
}

int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
	     struct hist_entry *he, hpp_field_fn get_field,
	     const char *fmtstr, hpp_snprint_fn print_fn,
	     enum perf_hpp_fmt_type fmtype)
{
	int len = max(fmt->user_len ?: fmt->len, (int)strlen(fmt->name));

	if (symbol_conf.field_sep) {
		return __hpp__fmt(hpp, he, get_field, fmtstr, 1,
				  print_fn, fmtype);
	}

	if (fmtype == PERF_HPP_FMT_TYPE__PERCENT || fmtype == PERF_HPP_FMT_TYPE__LATENCY)
		len -= 2; /* 2 for a space and a % sign */
	else
		len -= 1;

	return  __hpp__fmt(hpp, he, get_field, fmtstr, len, print_fn, fmtype);
}

Annotation

Implementation Notes