// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <linux/err.h>
#include <inttypes.h>
#include <math.h>
#include <string.h>
#include "counts.h"
#include "cpumap.h"
#include "debug.h"
#include "header.h"
#include "stat.h"
#include "session.h"
#include "target.h"
#include "evlist.h"
#include "evsel.h"
#include "thread_map.h"
#ifdef HAVE_LIBBPF_SUPPORT
#include <bpf/hashmap.h>
#else
#include "util/hashmap.h"
#endif
#include <linux/zalloc.h>

void update_stats(struct stats *stats, u64 val)
{
	double delta;

	stats->n++;
	delta = val - stats->mean;
	stats->mean += delta / stats->n;
	stats->M2 += delta*(val - stats->mean);

	if (val > stats->max)
		stats->max = val;

	if (val < stats->min)
		stats->min = val;
}

double avg_stats(struct stats *stats)
{
	return stats->mean;
}

/*
 * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
 *
 *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
 * s^2 = -------------------------------
 *                  n - 1
 *
 * http://en.wikipedia.org/wiki/Stddev
 *
 * The std dev of the mean is related to the std dev by:
 *
 *             s
 * s_mean = -------
 *          sqrt(n)
 *
 */
double stddev_stats(struct stats *stats)
{
	double variance, variance_mean;

	if (stats->n < 2)
		return 0.0;

	variance = stats->M2 / (stats->n - 1);
	variance_mean = variance / stats->n;

	return sqrt(variance_mean);
}

double rel_stddev_stats(double stddev, double avg)
{
	double pct = 0.0;

	if (avg)
		pct = 100.0 * stddev/avg;

	return pct;
}

bool __perf_stat_evsel__is(struct evsel *evsel, enum perf_stat_evsel_id id)
{
	struct perf_stat_evsel *ps = evsel->stats;

	return ps->id == id;
}

#define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
	ID(NONE,		x),
	ID(CYCLES_IN_TX,	cpu/cycles-t/),
	ID(TRANSACTION_START,	cpu/tx-start/),
	ID(ELISION_START,	cpu/el-start/),
	ID(CYCLES_IN_TX_CP,	cpu/cycles-ct/),
	ID(TOPDOWN_TOTAL_SLOTS, topdown-total-slots),
	ID(TOPDOWN_SLOTS_ISSUED, topdown-slots-issued),
	ID(TOPDOWN_SLOTS_RETIRED, topdown-slots-retired),
	ID(TOPDOWN_FETCH_BUBBLES, topdown-fetch-bubbles),
	ID(TOPDOWN_RECOVERY_BUBBLES, topdown-recovery-bubbles),
	ID(TOPDOWN_RETIRING, topdown-retiring),
	ID(TOPDOWN_BAD_SPEC, topdown-bad-spec),
	ID(TOPDOWN_FE_BOUND, topdown-fe-bound),
	ID(TOPDOWN_BE_BOUND, topdown-be-bound),
	ID(TOPDOWN_HEAVY_OPS, topdown-heavy-ops),
	ID(TOPDOWN_BR_MISPREDICT, topdown-br-mispredict),
	ID(TOPDOWN_FETCH_LAT, topdown-fetch-lat),
	ID(TOPDOWN_MEM_BOUND, topdown-mem-bound),
	ID(SMI_NUM, msr/smi/),
	ID(APERF, msr/aperf/),
};
#undef ID

static void perf_stat_evsel_id_init(struct evsel *evsel)
{
	struct perf_stat_evsel *ps = evsel->stats;
	int i;

	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */

	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
		if (!strcmp(evsel__name(evsel), id_str[i]) ||
		    (strstr(evsel__name(evsel), id_str[i]) && evsel->pmu_name
		     && strstr(evsel__name(evsel), evsel->pmu_name))) {
			ps->id = i;
			break;
		}
	}
}

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

	init_stats(&ps->res_stats);
}

static int evsel__alloc_stat_priv(struct evsel *evsel)
{
	evsel->stats = zalloc(sizeof(struct perf_stat_evsel));
	if (evsel->stats == NULL)
		return -ENOMEM;
	perf_stat_evsel_id_init(evsel);
	evsel__reset_stat_priv(evsel);
	return 0;
}

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

	if (ps)
		zfree(&ps->group_data);
	zfree(&evsel->stats);
}

static int evsel__alloc_prev_raw_counts(struct evsel *evsel)
{
	int cpu_map_nr = evsel__nr_cpus(evsel);
	int nthreads = perf_thread_map__nr(evsel->core.threads);
	struct perf_counts *counts;

	counts = perf_counts__new(cpu_map_nr, nthreads);
	if (counts)
		evsel->prev_raw_counts = counts;

	return counts ? 0 : -ENOMEM;
}

static void evsel__free_prev_raw_counts(struct evsel *evsel)
{
	perf_counts__delete(evsel->prev_raw_counts);
	evsel->prev_raw_counts = NULL;
}

static void evsel__reset_prev_raw_counts(struct evsel *evsel)
{
	if (evsel->prev_raw_counts)
		perf_counts__reset(evsel->prev_raw_counts);
}

static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw)
{
	if (evsel__alloc_stat_priv(evsel) < 0 ||
	    evsel__alloc_counts(evsel) < 0 ||
	    (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0))
		return -ENOMEM;

	return 0;
}

int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw)
{
	struct evsel *evsel;

	evlist__for_each_entry(evlist, evsel) {
		if (evsel__alloc_stats(evsel, alloc_raw))
			goto out_free;
	}

	return 0;

out_free:
	evlist__free_stats(evlist);
	return -1;
}

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

	evlist__for_each_entry(evlist, evsel) {
		evsel__free_stat_priv(evsel);
		evsel__free_counts(evsel);
		evsel__free_prev_raw_counts(evsel);
	}
}

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

	evlist__for_each_entry(evlist, evsel) {
		evsel__reset_stat_priv(evsel);
		evsel__reset_counts(evsel);
	}
}

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

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

static void evsel__copy_prev_raw_counts(struct evsel *evsel)
{
	int idx, nthreads = perf_thread_map__nr(evsel->core.threads);

	for (int thread = 0; thread < nthreads; thread++) {
		perf_cpu_map__for_each_idx(idx, evsel__cpus(evsel)) {
			*perf_counts(evsel->counts, idx, thread) =
				*perf_counts(evsel->prev_raw_counts, idx, thread);
		}
	}

	evsel->counts->aggr = evsel->prev_raw_counts->aggr;
}

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

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

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

	/*
	 * To collect the overall statistics for interval mode,
	 * we copy the counts from evsel->prev_raw_counts to
	 * evsel->counts. The perf_stat_process_counter creates
	 * aggr values from per cpu values, but the per cpu values
	 * are 0 for AGGR_GLOBAL. So we use a trick that saves the
	 * previous aggr value to the first member of perf_counts,
	 * then aggr calculation in process_counter_values can work
	 * correctly.
	 */
	evlist__for_each_entry(evlist, evsel) {
		*perf_counts(evsel->prev_raw_counts, 0, 0) =
			evsel->prev_raw_counts->aggr;
	}
}

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__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)
		return -1;

	/*
	 * On multi-die system, die_id > 0. On no-die system, die_id = 0.
	 * We use hashmap(socket, die) to check the used socket+die pair.
	 */
	d = cpu__get_die_id(cpu);
	if (d < 0)
		return -1;

	key = malloc(sizeof(*key));
	if (!key)
		return -ENOMEM;

	*key = (uint64_t)d << 32 | s;
	if (hashmap__find(mask, key, NULL)) {
		*skip = true;
		free(key);
	} else
		ret = hashmap__add(mask, key, 1);

	return ret;
}

static int
process_counter_values(struct perf_stat_config *config, struct evsel *evsel,
		       int cpu_map_idx, int thread,
		       struct perf_counts_values *count)
{
	struct perf_counts_values *aggr = &evsel->counts->aggr;
	static struct perf_counts_values zero;
	bool skip = false;

	if (check_per_pkg(evsel, count, cpu_map_idx, &skip)) {
		pr_err("failed to read per-pkg counter\n");
		return -1;
	}

	if (skip)
		count = &zero;

	switch (config->aggr_mode) {
	case AGGR_THREAD:
	case AGGR_CORE:
	case AGGR_DIE:
	case AGGR_SOCKET:
	case AGGR_NODE:
	case AGGR_NONE:
		if (!evsel->snapshot)
			evsel__compute_deltas(evsel, cpu_map_idx, thread, count);
		perf_counts_values__scale(count, config->scale, NULL);
		if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) {
			perf_stat__update_shadow_stats(evsel, count->val,
						       cpu_map_idx, &rt_stat);
		}

		if (config->aggr_mode == AGGR_THREAD) {
			perf_stat__update_shadow_stats(evsel, count->val,
						       thread, &rt_stat);
		}
		break;
	case AGGR_GLOBAL:
		aggr->val += count->val;
		aggr->ena += count->ena;
		aggr->run += count->run;
	case AGGR_UNSET:
	case AGGR_MAX:
	default:
		break;
	}

	return 0;
}

static int process_counter_maps(struct perf_stat_config *config,
				struct evsel *counter)
{
	int nthreads = perf_thread_map__nr(counter->core.threads);
	int ncpus = evsel__nr_cpus(counter);
	int idx, thread;

	for (thread = 0; thread < nthreads; thread++) {
		for (idx = 0; idx < ncpus; idx++) {
			if (process_counter_values(config, counter, idx, thread,
						   perf_counts(counter->counts, idx, thread)))
				return -1;
		}
	}

	return 0;
}

int perf_stat_process_counter(struct perf_stat_config *config,
			      struct evsel *counter)
{
	struct perf_counts_values *aggr = &counter->counts->aggr;
	struct perf_stat_evsel *ps = counter->stats;
	u64 *count = counter->counts->aggr.values;
	int ret;

	aggr->val = aggr->ena = aggr->run = 0;

	if (counter->per_pkg)
		evsel__zero_per_pkg(counter);

	ret = process_counter_maps(config, counter);
	if (ret)
		return ret;

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

	if (!counter->snapshot)
		evsel__compute_deltas(counter, -1, -1, aggr);
	perf_counts_values__scale(aggr, config->scale, &counter->counts->scaled);

	update_stats(&ps->res_stats, *count);

	if (verbose > 0) {
		fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
			evsel__name(counter), count[0], count[1], count[2]);
	}

	/*
	 * Save the full runtime - to allow normalization during printout:
	 */
	perf_stat__update_shadow_stats(counter, *count, 0, &rt_stat);

	return 0;
}

int perf_event__process_stat_event(struct perf_session *session,
				   union perf_event *event)
{
	struct perf_counts_values count, *ptr;
	struct perf_record_stat *st = &event->stat;
	struct evsel *counter;
	int cpu_map_idx;

	count.val = st->val;
	count.ena = st->ena;
	count.run = st->run;

	counter = evlist__id2evsel(session->evlist, st->id);
	if (!counter) {
		pr_err("Failed to resolve counter for stat event.\n");
		return -EINVAL;
	}
	cpu_map_idx = perf_cpu_map__idx(evsel__cpus(counter), (struct perf_cpu){.cpu = st->cpu});
	if (cpu_map_idx == -1) {
		pr_err("Invalid CPU %d for event %s.\n", st->cpu, evsel__name(counter));
		return -EINVAL;
	}
	ptr = perf_counts(counter->counts, cpu_map_idx, st->thread);
	if (ptr == NULL) {
		pr_err("Failed to find perf count for CPU %d thread %d on event %s.\n",
			st->cpu, st->thread, evsel__name(counter));
		return -EINVAL;
	}
	*ptr = count;
	counter->supported = true;
	return 0;
}

size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp)
{
	struct perf_record_stat *st = (struct perf_record_stat *)event;
	size_t ret;

	ret  = fprintf(fp, "\n... id %" PRI_lu64 ", cpu %d, thread %d\n",
		       st->id, st->cpu, st->thread);
	ret += fprintf(fp, "... value %" PRI_lu64 ", enabled %" PRI_lu64 ", running %" PRI_lu64 "\n",
		       st->val, st->ena, st->run);

	return ret;
}

size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp)
{
	struct perf_record_stat_round *rd = (struct perf_record_stat_round *)event;
	size_t ret;

	ret = fprintf(fp, "\n... time %" PRI_lu64 ", type %s\n", rd->time,
		      rd->type == PERF_STAT_ROUND_TYPE__FINAL ? "FINAL" : "INTERVAL");

	return ret;
}

size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp)
{
	struct perf_stat_config sc;
	size_t ret;

	perf_event__read_stat_config(&sc, &event->stat_config);

	ret  = fprintf(fp, "\n");
	ret += fprintf(fp, "... aggr_mode %d\n", sc.aggr_mode);
	ret += fprintf(fp, "... scale     %d\n", sc.scale);
	ret += fprintf(fp, "... interval  %u\n", sc.interval);

	return ret;
}

int create_perf_stat_counter(struct evsel *evsel,
			     struct perf_stat_config *config,
			     struct target *target,
			     int cpu_map_idx)
{
	struct perf_event_attr *attr = &evsel->core.attr;
	struct evsel *leader = evsel__leader(evsel);

	attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
			    PERF_FORMAT_TOTAL_TIME_RUNNING;

	/*
	 * The event is part of non trivial group, let's enable
	 * the group read (for leader) and ID retrieval for all
	 * members.
	 */
	if (leader->core.nr_members > 1)
		attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP;

	attr->inherit = !config->no_inherit && list_empty(&evsel->bpf_counter_list);

	/*
	 * Some events get initialized with sample_(period/type) set,
	 * like tracepoints. Clear it up for counting.
	 */
	attr->sample_period = 0;

	if (config->identifier)
		attr->sample_type = PERF_SAMPLE_IDENTIFIER;

	if (config->all_user) {
		attr->exclude_kernel = 1;
		attr->exclude_user   = 0;
	}

	if (config->all_kernel) {
		attr->exclude_kernel = 0;
		attr->exclude_user   = 1;
	}

	/*
	 * Disabling all counters initially, they will be enabled
	 * either manually by us or by kernel via enable_on_exec
	 * set later.
	 */
	if (evsel__is_group_leader(evsel)) {
		attr->disabled = 1;

		/*
		 * In case of initial_delay we enable tracee
		 * events manually.
		 */
		if (target__none(target) && !config->initial_delay)
			attr->enable_on_exec = 1;
	}

	if (target__has_cpu(target) && !target__has_per_thread(target))
		return evsel__open_per_cpu(evsel, evsel__cpus(evsel), cpu_map_idx);

	return evsel__open_per_thread(evsel, evsel->core.threads);
}
