/*
 *  timerfd() test by Davide Libenzi (test app for timerfd)
 *  Copyright (C) 2007  Davide Libenzi
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Davide Libenzi <davidel@xmailserver.org>
 *
 *
 *     $ gcc -o timerfd-test2 timerfd-test2.c -lrt
 *
 * NAME
 *	timerfd01.c
 * HISTORY
 *	28/05/2008 Initial contribution by Davide Libenzi <davidel@xmailserver.org>
 *      28/05/2008 Integrated to LTP by Subrata Modak <subrata@linux.vnet.ibm.com>
 */

#define _GNU_SOURCE
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <poll.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include "test.h"
#include "linux_syscall_numbers.h"

#define cleanup tst_exit

char *TCID = "timerfd01";

/*
 * This were good at the time of 2.6.23-rc7 ...
 *
 * #ifdef __NR_timerfd
 *
 * ... but is not now with 2.6.25
 */
#ifdef __NR_timerfd_create

/* Definitions from include/linux/timerfd.h */
#define TFD_TIMER_ABSTIME (1 << 0)

struct tmr_type {
	int id;
	char const *name;
};

unsigned long long getustime(int clockid)
{
	struct timespec tp;

	if (clock_gettime((clockid_t) clockid, &tp)) {
		perror("clock_gettime");
		return 0;
	}

	return 1000000ULL * tp.tv_sec + tp.tv_nsec / 1000;
}

void set_timespec(struct timespec *tmr, unsigned long long ustime)
{

	tmr->tv_sec = (time_t) (ustime / 1000000ULL);
	tmr->tv_nsec = (long)(1000ULL * (ustime % 1000000ULL));
}

int timerfd_create(int clockid, int flags)
{

	return ltp_syscall(__NR_timerfd_create, clockid, flags);
}

int timerfd_settime(int ufc, int flags, const struct itimerspec *utmr,
		    struct itimerspec *otmr)
{

	return ltp_syscall(__NR_timerfd_settime, ufc, flags, utmr, otmr);
}

int timerfd_gettime(int ufc, struct itimerspec *otmr)
{

	return ltp_syscall(__NR_timerfd_gettime, ufc, otmr);
}

long waittmr(int tfd, int timeo)
{
	u_int64_t ticks;
	struct pollfd pfd;

	pfd.fd = tfd;
	pfd.events = POLLIN;
	pfd.revents = 0;
	if (poll(&pfd, 1, timeo) < 0) {
		perror("poll");
		return -1;
	}
	if ((pfd.revents & POLLIN) == 0) {
		fprintf(stdout, "no ticks happened\n");
		return -1;
	}
	if (read(tfd, &ticks, sizeof(ticks)) != sizeof(ticks)) {
		perror("timerfd read");
		return -1;
	}

	return ticks;
}

int TST_TOTAL = 3;

int main(int ac, char **av)
{
	int i, tfd;
	long ticks;
	unsigned long long tnow, ttmr;
	u_int64_t uticks;
	struct itimerspec tmr;
	struct tmr_type clks[] = {
		{CLOCK_MONOTONIC, "CLOCK MONOTONIC"},
		{CLOCK_REALTIME, "CLOCK REALTIME"},
	};

	if ((tst_kvercmp(2, 6, 25)) < 0) {
		tst_resm(TCONF, "This test can only run on kernels that are ");
		tst_resm(TCONF, "2.6.25 and higher");
		exit(0);
	}

	for (i = 0; i < sizeof(clks) / sizeof(clks[0]); i++) {
		fprintf(stdout,
			"\n\n---------------------------------------\n");
		fprintf(stdout, "| testing %s\n", clks[i].name);
		fprintf(stdout, "---------------------------------------\n\n");

		fprintf(stdout, "relative timer test (at 500 ms) ...\n");
		set_timespec(&tmr.it_value, 500 * 1000);
		set_timespec(&tmr.it_interval, 0);
		tnow = getustime(clks[i].id);
		if ((tfd = timerfd_create(clks[i].id, 0)) == -1) {
			perror("timerfd");
			return 1;
		}
		fprintf(stdout, "timerfd = %d\n", tfd);

		if (timerfd_settime(tfd, 0, &tmr, NULL)) {
			perror("timerfd_settime");
			return 1;
		}

		fprintf(stdout, "wating timer ...\n");
		ticks = waittmr(tfd, -1);
		ttmr = getustime(clks[i].id);
		if (ticks <= 0)
			fprintf(stdout, "whooops! no timer showed up!\n");
		else
			fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
				ticks, (ttmr - tnow) / 1000);

		fprintf(stdout, "absolute timer test (at 500 ms) ...\n");
		tnow = getustime(clks[i].id);
		set_timespec(&tmr.it_value, tnow + 500 * 1000);
		set_timespec(&tmr.it_interval, 0);
		if (timerfd_settime(tfd, TFD_TIMER_ABSTIME, &tmr, NULL)) {
			perror("timerfd_settime");
			return 1;
		}

		fprintf(stdout, "wating timer ...\n");
		ticks = waittmr(tfd, -1);
		ttmr = getustime(clks[i].id);
		if (ticks <= 0)
			fprintf(stdout, "whooops! no timer showed up!\n");
		else
			fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
				ticks, (ttmr - tnow) / 1000);

		fprintf(stdout, "sequential timer test (100 ms clock) ...\n");
		tnow = getustime(clks[i].id);
		set_timespec(&tmr.it_value, tnow + 100 * 1000);
		set_timespec(&tmr.it_interval, 100 * 1000);
		if (timerfd_settime(tfd, TFD_TIMER_ABSTIME, &tmr, NULL)) {
			perror("timerfd_settime");
			return 1;
		}

		fprintf(stdout, "sleeping 1 second ...\n");
		sleep(1);
		if (timerfd_gettime(tfd, &tmr)) {
			perror("timerfd_gettime");
			return 1;
		}
		fprintf(stdout, "timerfd_gettime returned:\n"
			"\tit_value = { %ld, %ld } it_interval = { %ld, %ld }\n",
			(long)tmr.it_value.tv_sec, (long)tmr.it_value.tv_nsec,
			(long)tmr.it_interval.tv_sec,
			(long)tmr.it_interval.tv_nsec);
		fprintf(stdout, "sleeping 1 second ...\n");
		sleep(1);

		fprintf(stdout, "wating timer ...\n");
		ticks = waittmr(tfd, -1);
		ttmr = getustime(clks[i].id);
		if (ticks <= 0)
			fprintf(stdout, "whooops! no timer showed up!\n");
		else
			fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
				ticks, (ttmr - tnow) / 1000);

		fprintf(stdout, "O_NONBLOCK test ...\n");
		tnow = getustime(clks[i].id);
		set_timespec(&tmr.it_value, 100 * 1000);
		set_timespec(&tmr.it_interval, 0);
		if (timerfd_settime(tfd, 0, &tmr, NULL)) {
			perror("timerfd_settime");
			return 1;
		}
		fprintf(stdout, "timerfd = %d\n", tfd);

		fprintf(stdout, "wating timer (flush the single tick) ...\n");
		ticks = waittmr(tfd, -1);
		ttmr = getustime(clks[i].id);
		if (ticks <= 0)
			fprintf(stdout, "whooops! no timer showed up!\n");
		else
			fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
				ticks, (ttmr - tnow) / 1000);

		fcntl(tfd, F_SETFL, fcntl(tfd, F_GETFL, 0) | O_NONBLOCK);

		if (read(tfd, &uticks, sizeof(uticks)) > 0)
			fprintf(stdout,
				"whooops! timer ticks not zero when should have been\n");
		else if (errno != EAGAIN)
			fprintf(stdout,
				"whooops! bad errno value (%d = '%s')!\n",
				errno, strerror(errno));
		else
			fprintf(stdout, "success\n");

		fcntl(tfd, F_SETFL, fcntl(tfd, F_GETFL, 0) & ~O_NONBLOCK);

		close(tfd);
	}

	tst_exit();
}

#else
int TST_TOTAL = 0;

int main(void)
{

	tst_brkm(TCONF, NULL,
		 "This test needs a kernel that has timerfd syscall.");
}
#endif
