// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <inttypes.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/mman.h>
#include <linux/string.h>

#include "tests.h"
#include "util/debug.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/cpumap.h"
#include "util/mmap.h"
#include "util/thread_map.h"
#include <perf/evlist.h>
#include <perf/mmap.h>

#define NR_LOOPS  10000000

/*
 * This test will open software clock events (cpu-clock, task-clock)
 * then check their frequency -> period conversion has no artifact of
 * setting period to 1 forcefully.
 */
static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
{
	int i, err = -1;
	volatile int tmp = 0;
	u64 total_periods = 0;
	int nr_samples = 0;
	char sbuf[STRERR_BUFSIZE];
	union perf_event *event;
	struct evsel *evsel;
	struct evlist *evlist;
	struct perf_event_attr attr = {
		.type = PERF_TYPE_SOFTWARE,
		.config = clock_id,
		.sample_type = PERF_SAMPLE_PERIOD,
		.exclude_kernel = 1,
		.disabled = 1,
		.freq = 1,
	};
	struct perf_cpu_map *cpus;
	struct perf_thread_map *threads;
	struct mmap *md;

	attr.sample_freq = 500;

	evlist = evlist__new();
	if (evlist == NULL) {
		pr_debug("evlist__new\n");
		return -1;
	}

	evsel = evsel__new(&attr);
	if (evsel == NULL) {
		pr_debug("evsel__new\n");
		goto out_delete_evlist;
	}
	evlist__add(evlist, evsel);

	cpus = perf_cpu_map__dummy_new();
	threads = thread_map__new_by_tid(getpid());
	if (!cpus || !threads) {
		err = -ENOMEM;
		pr_debug("Not enough memory to create thread/cpu maps\n");
		goto out_free_maps;
	}

	perf_evlist__set_maps(&evlist->core, cpus, threads);

	cpus	= NULL;
	threads = NULL;

	if (evlist__open(evlist)) {
		const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";

		err = -errno;
		pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
			 str_error_r(errno, sbuf, sizeof(sbuf)),
			 knob, (u64)attr.sample_freq);
		goto out_delete_evlist;
	}

	err = evlist__mmap(evlist, 128);
	if (err < 0) {
		pr_debug("failed to mmap event: %d (%s)\n", errno,
			 str_error_r(errno, sbuf, sizeof(sbuf)));
		goto out_delete_evlist;
	}

	evlist__enable(evlist);

	/* collect samples */
	for (i = 0; i < NR_LOOPS; i++)
		tmp++;

	evlist__disable(evlist);

	md = &evlist->mmap[0];
	if (perf_mmap__read_init(&md->core) < 0)
		goto out_init;

	while ((event = perf_mmap__read_event(&md->core)) != NULL) {
		struct perf_sample sample;

		if (event->header.type != PERF_RECORD_SAMPLE)
			goto next_event;

		err = perf_evlist__parse_sample(evlist, event, &sample);
		if (err < 0) {
			pr_debug("Error during parse sample\n");
			goto out_delete_evlist;
		}

		total_periods += sample.period;
		nr_samples++;
next_event:
		perf_mmap__consume(&md->core);
	}
	perf_mmap__read_done(&md->core);

out_init:
	if ((u64) nr_samples == total_periods) {
		pr_debug("All (%d) samples have period value of 1!\n",
			 nr_samples);
		err = -1;
	}

out_free_maps:
	perf_cpu_map__put(cpus);
	perf_thread_map__put(threads);
out_delete_evlist:
	evlist__delete(evlist);
	return err;
}

int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_unused)
{
	int ret;

	ret = __test__sw_clock_freq(PERF_COUNT_SW_CPU_CLOCK);
	if (!ret)
		ret = __test__sw_clock_freq(PERF_COUNT_SW_TASK_CLOCK);

	return ret;
}
