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

int main();
void bail();
int nullFunction();
void initExp(int off, char *conf);
void startExp(char *desc);
void startTime();
void stopTime(int loops);

/**
 * A quick and dirty program to get a rough idea of the cost of a
 * function call and a null system call in Unix.
 */
int main(int argc, char **argv)
{
	int tries, loops;
	int numberOfLoops = 1000000;
	int rc;

#if CONF == 0
	initExp(1, "noopt");
#else
	initExp(5, "opt");
#endif

	startExp("cTimerOffset");
	for (tries = 0; tries<10; tries++) {
		startTime();
		stopTime(1);
	}

	startExp("cEmptyLoop");
	for (tries = 0; tries<10; tries++) {
		startTime();
		for (loops=0; loops<numberOfLoops; loops++) {
		}
		stopTime(loops);
	}

	startExp("cNullFcn");
	for (tries = 0; tries<10; tries++) {
		startTime();
		for (loops=0; loops<numberOfLoops; loops++) {
			rc = nullFunction();
		}
		stopTime(loops);
	}

	startExp("cGetPID");
	for (tries = 0; tries<10; tries++) {
		startTime();
		for (loops=0; loops<numberOfLoops; loops++) {
			rc = getpid();
		}
		stopTime(loops);
	}
}

int nullFunction()
{
	return -7;
}

static struct timeval ts1;
static struct timeval ts2;
static int expNumStatic=0;
static char *confDesc;

void initExp(int off, char *conf)
{
	expNumStatic = off-1;
	confDesc = conf;
}

void startExp(char *desc)
{
	expNumStatic++;
	printf("EXP %d experimentID %d\n", expNumStatic, expNumStatic);
	printf("EXP %d desc %s\n", expNumStatic, desc);
	printf("EXP %d conf %s\n", expNumStatic, confDesc);
}

void startTime(int expNum, char *desc)
{
	gettimeofday(&ts1, NULL);
}

void stopTime(int loops)
{
	gettimeofday(&ts2, NULL);
	ts2.tv_sec -= ts1.tv_sec;
	ts2.tv_usec -= ts1.tv_usec;
	if (ts2.tv_usec < 0) {
		ts2.tv_sec-=1;
		ts2.tv_usec+=1000000;
	}
	printf("%d %d %d.%06d %d\n",
		expNumStatic, loops, ts2.tv_sec, ts2.tv_usec, -1);
}

void bail()
{
	fprintf(stderr, "something bites, dude. Dude, errno is %d.\n", errno);
	perror("laaaaame");
	exit(1);
}
