#include <stdio.h>
#include <pthread.h>

#include "timer.h"

pthread_mutex_t lock;
double totTime;
int x;

/*-----------------------------------------------------------------------------
 Function name: ping
 -------------------------------------------------------------------------------
 Preconditions:
	-None
 Postconditions:
	-None
 Algorithm:
	-Set x to one, once the lock is held
	-Wait on x=2
 Exception/Error Handlig:
	-None
 -----------------------------------------------------------------------------*/

void *ping (void *args)
{
	pthread_mutex_lock (&lock);

	x = 1;
	pthread_mutex_unlock (&lock);

	while (x != 2)
	{
	}

	pthread_exit (NULL);
}

/*-----------------------------------------------------------------------------
 Function name: pong
 -------------------------------------------------------------------------------
 Preconditions:
	-None
 Postconditions:
	-The global x is set to 2
 Algorithm:
	-Wait for x to be 1
	-Lock x and set it to 2
 Exception/Error Handlig:
	-
 -----------------------------------------------------------------------------*/
void *pong (void *args)
{
	while (x != 1)
	{
	}

	pthread_mutex_lock (&lock);

	x=2;
	pthread_mutex_unlock (&lock);

	pthread_exit (NULL);
}

/*-----------------------------------------------------------------------------
 Function name: main 
 -------------------------------------------------------------------------------
 Preconditions:
	-None
 Postconditions:
	-None
 Algorithm:
	-Default all values
	-For 100000 times create the 2 threads that talk to each other
	-Output the average
 Exception/Error Handlig:
	-None
 -----------------------------------------------------------------------------*/
int main ( )
{
	int i;
	pthread_t pinger, ponger;

	timer watch;

	totTime = 0.0f;

	for (i=0; i<1000000; i++)
	{
		x = 0;

		watch.start ();
		
		pthread_create (&pinger, NULL, ping, NULL);

		pthread_create (&ponger, NULL, pong, NULL);
		pthread_join (ponger, NULL);

		pthread_join (pinger, NULL);
		watch.stop ();

        	if (i > 1000 && i < 99000)
        	{
			totTime += watch.read ();
	        }

		watch.reset ();
	}

	printf ("%.3f\n", totTime/980000.0f);

	return 0;
}