/*
 * (C) Finite State Machine Labs Inc. 2000 business@fsmlabs.com
 *
 * Released under the terms of GPL 2.
 * Open RTLinux makes use of a patented process described in
 * US Patent 5,995,745. Use of this process is governed
 * by the Open RTLinux Patent License which can be obtained from
 * www.fsmlabs.com/PATENT or by sending email to
 * licensequestions@fsmlabs.com
 */

#include <stdio.h>
#include <errno.h>
#include <rtlinux_signal.h>

/* number of tests to run */
#define NUM_TESTS	32

/* time between each test */
#define HANGTIME	(NSECS_PER_SEC / 32)

hrtime_t all_times[NUM_TESTS];
volatile int testnum;

void myhandler(int whatever)
{
	if (testnum < NUM_TESTS) {
		all_times[testnum] = gethrtime();
		testnum++;
	}
}

int main(void)
{
	struct rtlinux_sigaction mysig, oldsig;
	hrtime_t cur_drift, avg_drift, diff_time, worst_drift;
	int i;

	worst_drift = 0;
	avg_drift = 0;
	testnum = 0;

	mysig.sa_handler = myhandler;
	mysig.sa_flags = RTLINUX_SA_PERIODIC;
	mysig.sa_period = HANGTIME;

	if ((rtlinux_sigaction(RTLINUX_SIGTIMER0, &mysig, &oldsig))) {
		perror("rtlinux_sigaction");
		return (-1);
	}

	while (testnum < NUM_TESTS)
		sleep(1);

	mysig.sa_handler = RTLINUX_SIG_IGN;
	if ((rtlinux_sigaction(RTLINUX_SIGTIMER0, &mysig, &oldsig))) {
		perror("rtlinux_sigaction");
		return (-1);
	}

	for (i = 1; i < NUM_TESTS; i++) {
		diff_time = all_times[i] - all_times[i - 1];
		cur_drift =
		    (diff_time <
		     HANGTIME) ? (HANGTIME -
				  diff_time) : (diff_time - HANGTIME);
		avg_drift += cur_drift;
		worst_drift =
		    (worst_drift < cur_drift) ? cur_drift : worst_drift;
	}

	avg_drift /= NUM_TESTS;
	/* check to see if the worst case time was 50000 nanoseconds (50
	 * microseconds) or more */

	fprintf(stderr,
		"avg_drift: %d.%02d us\tworst_drift: %d.%02d us\n",
		(long) avg_drift / 1000, (long) (avg_drift % 1000) / 10,
		(long) worst_drift / 1000,
		(long) (worst_drift % 1000) / 10);
	if (worst_drift >= 50000) {
		return (-1);
	}


	return (0);
}
