/*----------------------------------------------------------------------------
Name: realtimer.c (implimentation of gettimeofday)
Author: Christopher Huyler
Date: March 13, 2002
Description: realtimer API
Provides start_real and get_real functions to keep track of time
API overrides the SIGALRM signal using the _incr_real signal handler.
----------------------------------------------------------------------------*/
#include <sys/time.h>
#include <signal.h>

struct itimerval _r;                    // itimer initializer (private)
static long _real_time;              	// real time (private)

void _incr_real(int);					// signal handler (private)
int  start_real(void);					// start the real timer
void reset_real(void);					// reset the real timer to zero
void set_real(void);      				// initialize timer to current time
struct timeval get_real(void);			// get current time
long elapsed_usecs(long,long);


/*  incriment clock signal handler -------------------------------------------
	input		- signal type integer
	output		- incriments real_time by one second every time called
	syscalls	- calls signal to re-register itself */
void _incr_real(int sig)
{
	_real_time++;							// incriment real time
	signal(SIGALRM,_incr_real);     		// reset signal
}

/*	start real timer ---------------------------------------------------------
	input		- nothing
	output		- initializes an itimer and registers a SIGALRM signal handler
	syscalls	- calls signal and setitimer */
int start_real()
{
	signal(SIGALRM,_incr_real);				// register signal handler
		
	_r.it_interval.tv_sec = 1;				// set interval seconds
	_r.it_interval.tv_usec = 0;				// set interval microseconds
	_r.it_value.tv_sec = 1;					// set start seconds value
	_r.it_value.tv_usec = 0;				// set start useconds value
	
	setitimer(ITIMER_REAL, &_r, NULL);		// start the timer
}

/*	reset real timer ---------------------------------------------------------
	input		- nothing
	output		- resets real time timeval
	syscalls	- none */
void reset_real()
{
	_real_time = 0;
}

/*	get current clock time ---------------------------------------------------
	input		- reads clock_time variable
	output		- returns real_time value + current itimer value
	syscalls	- calls getitimer */
struct timeval get_real()
{
	struct timeval current_time;
	getitimer(ITIMER_REAL,&_r);				// get current timer state
	current_time.tv_sec = _real_time;		// and add it to real time
	current_time.tv_usec = elapsed_usecs(_r.it_value.tv_sec, _r.it_value.tv_usec); // time = start - remaining
	return current_time;
}

long elapsed_usecs(long sec, long usec) {
	long us = 0;
//	if(sec > 0)
//		us += (1 - sec) * 1000000;
	if(usec > 0)
		us += 1000000 - usec;
	return us;
}	
/*	test function for clock --------------------------------------------------
	input		- nothing
	output		- prints out real time recursively using realtimer functions
	syscalls	- none
int main() {
	struct timeval myTime;
	start_real();
	while(1) {
		getitimer(ITIMER_REAL,&_r);
		printf("\n%ld ld seconds, %ld microseconds",_r.it_value.tv_sec,_r.it_value.tv_usec);	
		myTime = get_real();
		printf("\n%ld seconds, %ld microseconds",
				myTime.tv_sec,
				myTime.tv_usec);
	}
} */
