// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2013 Red Hat, Inc., Frederic Weisbecker <fweisbec@redhat.com>
 *
 * Selftests for a few posix timers interface.
 *
 * Kernel loop code stolen from Steven Rostedt <srostedt@redhat.com>
 */

#include <sys/time.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>

#include "../kselftest.h"

#define DELAY 2
#define USECS_PER_SEC 1000000

static volatile int done;

/* Busy loop in userspace to elapse ITIMER_VIRTUAL */
static void user_loop(void)
{
	while (!done);
}

/*
 * Try to spend as much time as possible in kernelspace
 * to elapse ITIMER_PROF.
 */
static void kernel_loop(void)
{
	void *addr = sbrk(0);
	int err = 0;

	while (!done && !err) {
		err = brk(addr + 4096);
		err |= brk(addr);
	}
}

/*
 * Sleep until ITIMER_REAL expiration.
 */
static void idle_loop(void)
{
	pause();
}

static void sig_handler(int nr)
{
	done = 1;
}

/*
 * Check the expected timer expiration matches the GTOD elapsed delta since
 * we armed the timer. Keep a 0.5 sec error margin due to various jitter.
 */
static int check_diff(struct timeval start, struct timeval end)
{
	long long diff;

	diff = end.tv_usec - start.tv_usec;
	diff += (end.tv_sec - start.tv_sec) * USECS_PER_SEC;

	if (abs(diff - DELAY * USECS_PER_SEC) > USECS_PER_SEC / 2) {
		printf("Diff too high: %lld..", diff);
		return -1;
	}

	return 0;
}

static int check_itimer(int which)
{
	int err;
	struct timeval start, end;
	struct itimerval val = {
		.it_value.tv_sec = DELAY,
	};

	printf("Check itimer ");

	if (which == ITIMER_VIRTUAL)
		printf("virtual... ");
	else if (which == ITIMER_PROF)
		printf("prof... ");
	else if (which == ITIMER_REAL)
		printf("real... ");

	fflush(stdout);

	done = 0;

	if (which == ITIMER_VIRTUAL)
		signal(SIGVTALRM, sig_handler);
	else if (which == ITIMER_PROF)
		signal(SIGPROF, sig_handler);
	else if (which == ITIMER_REAL)
		signal(SIGALRM, sig_handler);

	err = gettimeofday(&start, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	err = setitimer(which, &val, NULL);
	if (err < 0) {
		perror("Can't set timer\n");
		return -1;
	}

	if (which == ITIMER_VIRTUAL)
		user_loop();
	else if (which == ITIMER_PROF)
		kernel_loop();
	else if (which == ITIMER_REAL)
		idle_loop();

	err = gettimeofday(&end, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	if (!check_diff(start, end))
		printf("[OK]\n");
	else
		printf("[FAIL]\n");

	return 0;
}

static int check_timer_create(int which)
{
	int err;
	timer_t id;
	struct timeval start, end;
	struct itimerspec val = {
		.it_value.tv_sec = DELAY,
	};

	printf("Check timer_create() ");
	if (which == CLOCK_THREAD_CPUTIME_ID) {
		printf("per thread... ");
	} else if (which == CLOCK_PROCESS_CPUTIME_ID) {
		printf("per process... ");
	}
	fflush(stdout);

	done = 0;
	err = timer_create(which, NULL, &id);
	if (err < 0) {
		perror("Can't create timer\n");
		return -1;
	}
	signal(SIGALRM, sig_handler);

	err = gettimeofday(&start, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	err = timer_settime(id, 0, &val, NULL);
	if (err < 0) {
		perror("Can't set timer\n");
		return -1;
	}

	user_loop();

	err = gettimeofday(&end, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	if (!check_diff(start, end))
		printf("[OK]\n");
	else
		printf("[FAIL]\n");

	return 0;
}

int remain;
__thread int got_signal;

static void *distribution_thread(void *arg)
{
	while (__atomic_load_n(&remain, __ATOMIC_RELAXED));
	return NULL;
}

static void distribution_handler(int nr)
{
	if (!__atomic_exchange_n(&got_signal, 1, __ATOMIC_RELAXED))
		__atomic_fetch_sub(&remain, 1, __ATOMIC_RELAXED);
}

/*
 * Test that all running threads _eventually_ receive CLOCK_PROCESS_CPUTIME_ID
 * timer signals. This primarily tests that the kernel does not favour any one.
 */
static int check_timer_distribution(void)
{
	int err, i;
	timer_t id;
	const int nthreads = 10;
	pthread_t threads[nthreads];
	struct itimerspec val = {
		.it_value.tv_sec = 0,
		.it_value.tv_nsec = 1000 * 1000,
		.it_interval.tv_sec = 0,
		.it_interval.tv_nsec = 1000 * 1000,
	};

	printf("Check timer_create() per process signal distribution... ");
	fflush(stdout);

	remain = nthreads + 1;  /* worker threads + this thread */
	signal(SIGALRM, distribution_handler);
	err = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
	if (err < 0) {
		perror("Can't create timer\n");
		return -1;
	}
	err = timer_settime(id, 0, &val, NULL);
	if (err < 0) {
		perror("Can't set timer\n");
		return -1;
	}

	for (i = 0; i < nthreads; i++) {
		if (pthread_create(&threads[i], NULL, distribution_thread, NULL)) {
			perror("Can't create thread\n");
			return -1;
		}
	}

	/* Wait for all threads to receive the signal. */
	while (__atomic_load_n(&remain, __ATOMIC_RELAXED));

	for (i = 0; i < nthreads; i++) {
		if (pthread_join(threads[i], NULL)) {
			perror("Can't join thread\n");
			return -1;
		}
	}

	if (timer_delete(id)) {
		perror("Can't delete timer\n");
		return -1;
	}

	printf("[OK]\n");
	return 0;
}

int main(int argc, char **argv)
{
	printf("Testing posix timers. False negative may happen on CPU execution \n");
	printf("based timers if other threads run on the CPU...\n");

	if (check_itimer(ITIMER_VIRTUAL) < 0)
		return ksft_exit_fail();

	if (check_itimer(ITIMER_PROF) < 0)
		return ksft_exit_fail();

	if (check_itimer(ITIMER_REAL) < 0)
		return ksft_exit_fail();

	if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
		return ksft_exit_fail();

	/*
	 * It's unfortunately hard to reliably test a timer expiration
	 * on parallel multithread cputime. We could arm it to expire
	 * on DELAY * nr_threads, with nr_threads busy looping, then wait
	 * the normal DELAY since the time is elapsing nr_threads faster.
	 * But for that we need to ensure we have real physical free CPUs
	 * to ensure true parallelism. So test only one thread until we
	 * find a better solution.
	 */
	if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
		return ksft_exit_fail();

	if (check_timer_distribution() < 0)
		return ksft_exit_fail();

	return ksft_exit_pass();
}
