#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>

double loops_per_ms;

double elapsed_time(struct timeval *tv1, struct timeval *tv2)
{
	double d1, d2;
	int elapsed_ms;

	d1 = tv1->tv_sec + tv1->tv_usec * 1e-6;
	d2 = tv2->tv_sec + tv2->tv_usec * 1e-6;
	elapsed_ms = (d2 - d1) * 1000;

	return elapsed_ms;
}

void calibrate_delay(void)
{
	int i;
	double elapsed_ms;
	struct timeval tv1, tv2;

	gettimeofday(&tv1, NULL);
#define LOOP_COUNT 100000000
	for (i=0; i < LOOP_COUNT; ++i)
		;
	gettimeofday(&tv2, NULL);
	elapsed_ms = elapsed_time(&tv1, &tv2);
	loops_per_ms = LOOP_COUNT / elapsed_ms;

	printf ("loops_per_ms = %f \n", loops_per_ms);
}

int run_length  = 52; 	// in milliseconds
int sleep_length = 24;	// in milliseconds
int epoch_time = 5;	// in seconds

main(int argc, char *argv[])
{
	long int i, delay;
	time_t prevtime;
	double prevusage = 0;
	struct rusage stats;

	if (argc > 1) {
		run_length = atoi(argv[1]);
		if (argc > 2)
			sleep_length = atoi(argv[2]);
		if (argc > 3)
			epoch_time = atoi(argv[3]);
	}

	calibrate_delay();

	delay = run_length * loops_per_ms;

	printf ("run time = %d ms (%ld loops), sleep time = %d ms,"
		" epoch time = %d s\n", run_length, delay, sleep_length,
		 epoch_time);

	prevtime = time(NULL);
	while (1) {
		time_t curtime, deltatime;
		struct rusage stats;

		for (i = 0; i < delay; ++i)
			;
		usleep(sleep_length * 1000);

		curtime = time(NULL);
		deltatime = curtime - prevtime;
		if (deltatime >= epoch_time) {
			double curusage, deltausage;

			getrusage(0, &stats);
			curusage = stats.ru_utime.tv_sec +
				   stats.ru_utime.tv_usec * 1e-6 +
				   stats.ru_stime.tv_sec + 
				   stats.ru_stime.tv_usec * 1e-6;

			deltausage = curusage - prevusage;
			printf ("Obtained %3.2f seconds of execution time in"
		       	      " %d elapsed seconds \n", deltausage, deltatime);
			prevtime = curtime;
			prevusage = curusage;
		}
	}
}