/*
 * Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com)
 * Licensed under the GPL
 */

#include <stddef.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <kern_util.h>
#include <os.h>
#include "internal.h"

int set_interval(void)
{
	int usec = UM_USEC_PER_SEC / UM_HZ;
	struct itimerval interval = ((struct itimerval) { { 0, usec },
							  { 0, usec } });

	if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
		return -errno;

	return 0;
}

int timer_one_shot(int ticks)
{
	unsigned long usec = ticks * UM_USEC_PER_SEC / UM_HZ;
	unsigned long sec = usec / UM_USEC_PER_SEC;
	struct itimerval interval;

	usec %= UM_USEC_PER_SEC;
	interval = ((struct itimerval) { { 0, 0 }, { sec, usec } });

	if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
		return -errno;

	return 0;
}

/**
 * timeval_to_ns - Convert timeval to nanoseconds
 * @ts:		pointer to the timeval variable to be converted
 *
 * Returns the scalar nanosecond representation of the timeval
 * parameter.
 *
 * Ripped from linux/time.h because it's a kernel header, and thus
 * unusable from here.
 */
static inline long long timeval_to_ns(const struct timeval *tv)
{
	return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
		tv->tv_usec * UM_NSEC_PER_USEC;
}

long long disable_timer(void)
{
	struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
	long long remain, max = UM_NSEC_PER_SEC / UM_HZ;

	if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
		printk(UM_KERN_ERR "disable_timer - setitimer failed, "
		       "errno = %d\n", errno);

	remain = timeval_to_ns(&time.it_value);
	if (remain > max)
		remain = max;

	return remain;
}

long long os_nsecs(void)
{
	struct timeval tv;

	gettimeofday(&tv, NULL);
	return timeval_to_ns(&tv);
}

#ifdef UML_CONFIG_NO_HZ_COMMON
static int after_sleep_interval(struct timespec *ts)
{
	return 0;
}

static void deliver_alarm(void)
{
	alarm_handler(SIGVTALRM, NULL, NULL);
}

static unsigned long long sleep_time(unsigned long long nsecs)
{
	return nsecs;
}

#else
unsigned long long last_tick;
unsigned long long skew;

static void deliver_alarm(void)
{
	unsigned long long this_tick = os_nsecs();
	int one_tick = UM_NSEC_PER_SEC / UM_HZ;

	/* Protection against the host's time going backwards */
	if ((last_tick != 0) && (this_tick < last_tick))
		this_tick = last_tick;

	if (last_tick == 0)
		last_tick = this_tick - one_tick;

	skew += this_tick - last_tick;

	while (skew >= one_tick) {
		alarm_handler(SIGVTALRM, NULL, NULL);
		skew -= one_tick;
	}

	last_tick = this_tick;
}

static unsigned long long sleep_time(unsigned long long nsecs)
{
	return nsecs > skew ? nsecs - skew : 0;
}

static inline long long timespec_to_us(const struct timespec *ts)
{
	return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
		ts->tv_nsec / UM_NSEC_PER_USEC;
}

static int after_sleep_interval(struct timespec *ts)
{
	int usec = UM_USEC_PER_SEC / UM_HZ;
	long long start_usecs = timespec_to_us(ts);
	struct timeval tv;
	struct itimerval interval;

	/*
	 * It seems that rounding can increase the value returned from
	 * setitimer to larger than the one passed in.  Over time,
	 * this will cause the remaining time to be greater than the
	 * tick interval.  If this happens, then just reduce the first
	 * tick to the interval value.
	 */
	if (start_usecs > usec)
		start_usecs = usec;

	start_usecs -= skew / UM_NSEC_PER_USEC;
	if (start_usecs < 0)
		start_usecs = 0;

	tv = ((struct timeval) { .tv_sec  = start_usecs / UM_USEC_PER_SEC,
				 .tv_usec = start_usecs % UM_USEC_PER_SEC });
	interval = ((struct itimerval) { { 0, usec }, tv });

	if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
		return -errno;

	return 0;
}
#endif

void idle_sleep(unsigned long long nsecs)
{
	struct timespec ts;

	/*
	 * nsecs can come in as zero, in which case, this starts a
	 * busy loop.  To prevent this, reset nsecs to the tick
	 * interval if it is zero.
	 */
	if (nsecs == 0)
		nsecs = UM_NSEC_PER_SEC / UM_HZ;

	nsecs = sleep_time(nsecs);
	ts = ((struct timespec) { .tv_sec	= nsecs / UM_NSEC_PER_SEC,
				  .tv_nsec	= nsecs % UM_NSEC_PER_SEC });

	if (nanosleep(&ts, &ts) == 0)
		deliver_alarm();
	after_sleep_interval(&ts);
}
