/* 
 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
#include "signal_user.h"
#include "time_user.h"
#include "kern_constants.h"

/* XXX This really needs to be declared and initialized in a kernel file since
 * it's in <linux/time.h>
 */
extern struct timespec wall_to_monotonic;

extern struct timeval xtime;

struct timeval local_offset = { 0, 0 };

void timer(void)
{
	gettimeofday(&xtime, NULL);
	timeradd(&xtime, &local_offset, &xtime);
}

static void set_interval(int timer_type)
{
	int usec = 1000000/hz();
	struct itimerval interval = ((struct itimerval) { { 0, usec },
							  { 0, usec } });

	if(setitimer(timer_type, &interval, NULL) == -1)
		panic("setitimer failed - errno = %d\n", errno);
}

void enable_timer(void)
{
	set_interval(ITIMER_VIRTUAL);
}

void prepare_timer(void * ptr)
{
	int usec = 1000000/hz();
	*(struct itimerval *)ptr = ((struct itimerval) { { 0, usec },
							 { 0, usec }});
}

void disable_timer(void)
{
	struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
	if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
	   (setitimer(ITIMER_REAL, &disable, NULL) < 0))
		printk("disnable_timer - setitimer failed, errno = %d\n",
		       errno);
	/* If there are signals already queued, after unblocking ignore them */
	set_handler(SIGALRM, SIG_IGN, 0, -1);
	set_handler(SIGVTALRM, SIG_IGN, 0, -1);
}

void switch_timers(int to_real)
{
	struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
	struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
							{ 0, 1000000/hz() }});
	int old, new;

	if(to_real){
		old = ITIMER_VIRTUAL;
		new = ITIMER_REAL;
	}
	else {
		old = ITIMER_REAL;
		new = ITIMER_VIRTUAL;
	}

	if((setitimer(old, &disable, NULL) < 0) ||
	   (setitimer(new, &enable, NULL)))
		printk("switch_timers - setitimer failed, errno = %d\n",
		       errno);
}

void uml_idle_timer(void)
{
	if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
		panic("Couldn't unset SIGVTALRM handler");
	
	set_handler(SIGALRM, (__sighandler_t) alarm_handler, 
		    SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
	set_interval(ITIMER_REAL);
}

extern int do_posix_clock_monotonic_gettime(struct timespec *tp);

void time_init(void)
{
	struct timespec now;

	if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
		panic("Couldn't set SIGVTALRM handler");
	set_interval(ITIMER_VIRTUAL);

	do_posix_clock_monotonic_gettime(&now);
	wall_to_monotonic.tv_sec = -now.tv_sec;
	wall_to_monotonic.tv_nsec = -now.tv_nsec;
}

/* Declared in linux/time.h, which can't be included here */
extern void clock_was_set(void);

void do_gettimeofday(struct timeval *tv)
{
	unsigned long flags;

	flags = time_lock();
	gettimeofday(tv, NULL);
	timeradd(tv, &local_offset, tv);
	time_unlock(flags);
	clock_was_set();
}

int do_settimeofday(struct timespec *tv)
{
	struct timeval now;
	unsigned long flags;
	struct timeval tv_in;

	if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
		return -EINVAL;

	tv_in.tv_sec = tv->tv_sec;
	tv_in.tv_usec = tv->tv_nsec / 1000;

	flags = time_lock();
	gettimeofday(&now, NULL);
	timersub(&tv_in, &now, &local_offset);
	time_unlock(flags);

	return(0);
}

void idle_sleep(int secs)
{
	struct timespec ts;

	ts.tv_sec = secs;
	ts.tv_nsec = 0;
	nanosleep(&ts, NULL);
}

/* XXX This partly duplicates init_irq_signals */

void user_time_init(void)
{
	set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
		    SIGALRM, SIGUSR2, -1);
	set_handler(SIGALRM, (__sighandler_t) alarm_handler,
		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
		    SIGVTALRM, SIGUSR2, -1);
	set_interval(ITIMER_VIRTUAL);
}
