/* %Z%%M% %I% %E% */

/*
 * Copyright (c) 1994-2004 Wayne C. Gramlich.
 * All rights reserved.
 */

/*
 * This file implements an interface to the high resolution timer.
 */

#ifndef MEMORY_H
#include "memory.h"
#endif

#ifndef STHEADERS_H
#include "stheaders.h"
#endif

#ifndef STR_EXPORTS_H
#include "str_exports.h"
#endif

#ifndef UNIX_ASSERT_H
#include "unix_assert.h"
#endif

#ifndef UNIX_SYS_TIME_H
#include "unix_sys_time.h"
#endif

typedef struct Time_struct *Time, Time_struct;

struct Time_struct {
	unsigned	seconds;	/* Number of seconds */
	unsigned	nanoseconds;	/* Number of nanoseconds */
};

static Time_struct time_struct = {
	0,
	0
};

Time time___initial = &time_struct;

static object___object time_initial_object = {
	"",				/* Package name */
	"time",				/* Type name */
	"??",				/* Object name */
	(type___reference *)0,		/*XXX: Fix me */
	(int *)0,			/* Size of character object */
	0,				/* Static needs count */
	(need___entry *)0, 		/*XXX: Fix me Static needs */
	0,				/* Parameter needs count */
	(need___entry *)0, 		/* Parameter needs */
	(void **)&time___initial,	/* Object pointer */
	(instantiation___object *)0	/* Instantiation list */
};
static object___object *object_list[1] = {
	&time_initial_object,
};

void
time__external__initialize(void)
{
	extern module___object time__module__object;

	time__module__object.object_count = 1;
	time__module__object.objects = object_list;
}

/*
 * time__allocate()
 *	This routine will create and return a new {time} object.
 */
Time
time__allocate(void)
{
	Time	time;

	time = memory_alloc(Time);
	time->seconds = 0;
	time->nanoseconds = 0;
	return time;
}

/*
 * time__seconds_get(time)
 *	This routine will return the seconds field of {time}.
 */
unsigned
time__seconds_get(
	Time	time)
{
	return time->seconds;
}

/*
 * time__seconds_set(time, seconds)
 *	This routine will set the seconds field of {time} to {seconds}.
 */
void
time__seconds_set(
	Time		time,
	unsigned	seconds)
{
	time->seconds = seconds;
}

/*
 * time__nanoseconds_get(time)
 *	This routine will return the nanoseconds field of {time}.
 */
unsigned
time__nanoseconds_get(
	Time		time)
{
	return time->nanoseconds;
}

/*
 * time__nanoseconds_set(time, nanoseconds)
 *	This routine will set the nanoseconds field of {time} to {nanoseconds}.
 */
void
time__nanoseconds_set(
	Time		time,
	unsigned	nanoseconds)
{
	time->nanoseconds = nanoseconds;
}


/*
 * time__current_set(time)
 *	This routine will set the current time into {time}.
 */
void
time__current_set(
	Time	time)
{
#ifdef SOLARIS
	/* Use high resolution timer when it is available: */
	hrtime_t high_res_time;
	hrtime_t million;

	million = 1000000000;
	high_res_time = gethrtime();
	time->seconds = high_res_time / million;
	time->nanoseconds = high_res_time % million;
#endif /* SOLARIS */
#ifdef LINUX
	/* Otherwise, make do with the microsecond clock. */
	struct timeval time_value;

	assert(gettimeofday(&time_value, (struct timezone *)0) == 0);
	time->seconds = time_value.tv_sec;
	time->nanoseconds = time_value.tv_usec * 1000;
#endif /* LINUX */
#ifdef WINDOWS
	assert(0);
#endif /* WINDOWS */
}

