tools/perf/util/stat.c

Source file repositories/reference/linux-study-clean/tools/perf/util/stat.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/stat.c
Extension
.c
Size
16884 bytes
Lines
722
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

perf_cpu_map__for_each_idx(idx, evsel__cpus(evsel)) {
			*perf_counts(evsel->counts, idx, thread) =
				*perf_counts(evsel->prev_raw_counts, idx, thread);
		}
	}
}

void evlist__copy_prev_raw_counts(struct evlist *evlist)
{
	struct evsel *evsel;

	evlist__for_each_entry(evlist, evsel)
		evsel__copy_prev_raw_counts(evsel);
}

static void evsel__copy_res_stats(struct evsel *evsel)
{
	struct perf_stat_evsel *ps = evsel->stats;

	/*
	 * For GLOBAL aggregation mode, it updates the counts for each run
	 * in the evsel->stats.res_stats.  See perf_stat_process_counter().
	 */
	*ps->aggr[0].counts.values = avg_stats(&ps->res_stats);
}

void evlist__copy_res_stats(struct perf_stat_config *config, struct evlist *evlist)
{
	struct evsel *evsel;

	if (config->aggr_mode != AGGR_GLOBAL)
		return;

	evlist__for_each_entry(evlist, evsel)
		evsel__copy_res_stats(evsel);
}

static size_t pkg_id_hash(long __key, void *ctx __maybe_unused)
{
	uint64_t *key = (uint64_t *) __key;

	return *key & 0xffffffff;
}

static bool pkg_id_equal(long __key1, long __key2, void *ctx __maybe_unused)
{
	uint64_t *key1 = (uint64_t *) __key1;
	uint64_t *key2 = (uint64_t *) __key2;

	return *key1 == *key2;
}

static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals,
			 int cpu_map_idx, bool *skip)
{
	struct hashmap *mask = counter->per_pkg_mask;
	struct perf_cpu_map *cpus = evsel__cpus(counter);
	struct perf_cpu cpu = perf_cpu_map__cpu(cpus, cpu_map_idx);
	int s, d, ret = 0;
	uint64_t *key;

	*skip = false;

	if (!counter->per_pkg)
		return 0;

	if (perf_cpu_map__is_any_cpu_or_is_empty(cpus))
		return 0;

	if (!mask) {
		mask = hashmap__new(pkg_id_hash, pkg_id_equal, NULL);
		if (IS_ERR(mask))
			return -ENOMEM;

		counter->per_pkg_mask = mask;
	}

	/*
	 * we do not consider an event that has not run as a good
	 * instance to mark a package as used (skip=1). Otherwise
	 * we may run into a situation where the first CPU in a package
	 * is not running anything, yet the second is, and this function
	 * would mark the package as used after the first CPU and would
	 * not read the values from the second CPU.
	 */
	if (!(vals->run && vals->ena))
		return 0;

	s = cpu__get_socket_id(cpu);
	if (s < 0)

Annotation

Implementation Notes