162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <errno.h>
362306a36Sopenharmony_ci#include <stdlib.h>
462306a36Sopenharmony_ci#include <string.h>
562306a36Sopenharmony_ci#include "evsel.h"
662306a36Sopenharmony_ci#include "counts.h"
762306a36Sopenharmony_ci#include <perf/threadmap.h>
862306a36Sopenharmony_ci#include <linux/zalloc.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistruct perf_counts *perf_counts__new(int ncpus, int nthreads)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci	struct perf_counts *counts = zalloc(sizeof(*counts));
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci	if (counts) {
1562306a36Sopenharmony_ci		struct xyarray *values;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci		values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
1862306a36Sopenharmony_ci		if (!values) {
1962306a36Sopenharmony_ci			free(counts);
2062306a36Sopenharmony_ci			return NULL;
2162306a36Sopenharmony_ci		}
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci		counts->values = values;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci		values = xyarray__new(ncpus, nthreads, sizeof(bool));
2662306a36Sopenharmony_ci		if (!values) {
2762306a36Sopenharmony_ci			xyarray__delete(counts->values);
2862306a36Sopenharmony_ci			free(counts);
2962306a36Sopenharmony_ci			return NULL;
3062306a36Sopenharmony_ci		}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci		counts->loaded = values;
3362306a36Sopenharmony_ci	}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	return counts;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_civoid perf_counts__delete(struct perf_counts *counts)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	if (counts) {
4162306a36Sopenharmony_ci		xyarray__delete(counts->loaded);
4262306a36Sopenharmony_ci		xyarray__delete(counts->values);
4362306a36Sopenharmony_ci		free(counts);
4462306a36Sopenharmony_ci	}
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_civoid perf_counts__reset(struct perf_counts *counts)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	xyarray__reset(counts->loaded);
5062306a36Sopenharmony_ci	xyarray__reset(counts->values);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_civoid evsel__reset_counts(struct evsel *evsel)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	perf_counts__reset(evsel->counts);
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciint evsel__alloc_counts(struct evsel *evsel)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	struct perf_cpu_map *cpus = evsel__cpus(evsel);
6162306a36Sopenharmony_ci	int nthreads = perf_thread_map__nr(evsel->core.threads);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	evsel->counts = perf_counts__new(perf_cpu_map__nr(cpus), nthreads);
6462306a36Sopenharmony_ci	return evsel->counts != NULL ? 0 : -ENOMEM;
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_civoid evsel__free_counts(struct evsel *evsel)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	perf_counts__delete(evsel->counts);
7062306a36Sopenharmony_ci	evsel->counts = NULL;
7162306a36Sopenharmony_ci}
72