#include 
#include 
#include 
#include 
#include 

/*      ASSUMPTIONS
1.      Only up to 5 savages can attend the tribal communal dinner. (Test version only)
2.      There is no limit on how many savages can come within a given time.
3.      What they are eating is not missionary stew: it's "Survivor" stew. MWAHAHAHAHAHAHAHA!!!!!!
*/
	

/*global variables, threads, and mutexes*/

pthread_t thrSavage[5];
pthread_t thrCook;
pthread_mutex_t lEnter;
pthread_mutex_t lPot;
pthread_mutex_t lCall;
pthread_mutex_t lArrive;
int iNumArrive = 0;
int iCall = 0;
int iPot;


/*Process calls*/
void *savage (void *);
void *cook (void *);



/*main program*/

main()
{
        int iTime = 0;
        int iSavageArrive[5]; 	//stores the arrival time of savages
        int i;
        int j;
        int iTempNA; 		//temporary variable holding 
				//iNumArrive's max value
        int iIdArrive[5]; 	//stores the ID of those who 
				//arrived at present time

        /*initialization of mutex variables*/

        pthread_mutex_init(&lPot, pthread_mutexattr_default);
        pthread_mutex_init(&lCall, pthread_mutexattr_default);
        pthread_mutex_init(&lArrive, pthread_mutexattr_default);
	pthread_mutex_init(&lEnter, pthread_mutexattr_default);

        /*get input. Test version only*/

        for(i=0; i<1; i++)
        {
                printf("\nEnter Savage %d 's arrival time: ", i);
                scanf("%d", &iSavageArrive[i]);
        }
	
	//Initialize the pot to contain 2 servings of 
	//"Survivor" participants

	iPot = 0;

        /*MAIN LOOP STARTS HERE*/

        for(iTime = 0; iTime < 10; iTime++)
        {
		printf("\nTime: %d", iTime);

                iNumArrive = 0;
		j = 0;
                
		/*gets the ID's of those who arrived in this time*/
		
		for(i=0; i< 1; i++)
                {	if (iSavageArrive[i] == iTime)
			{
				iNumArrive++;
				iIdArrive[j] = i;
				printf("\nSavage %d ",iIdArrive[j]); 
				printf("arrived at time ");
				printf("%d.", iTime);
				j++;
			}
		}			

		//printf("\n %d", iNumArrive);

		
		//gets iNumArrive's value since the said variable will
		//decremented by the threads...
		iTempNA = iNumArrive;

		//start the cook thread here
	pthread_create(&thrCook, pthread_attr_default, cook, (void *) i);

		/*This for loop calls the threads of the savages who arrived at this time*/
		
		if (iNumArrive > 0)
		{
		for(i=0; i< 1; i++)
		{
		/*	for(j=0; j< iTempNA; j++)
			{
				if (i == iIdArrive[j])
				{
				  //call savage thread[i] here
		*/
pthread_create(&thrSavage[0], pthread_attr_default, savage, (void *) i);
				//} 
			//}
		}
		}

		//put the pthread join here joining this and the cook thread
		pthread_join(thrCook, NULL);
        }

	sleep(3);
	printf("\nNo one wins Survivor.");
	printf(" The savages get the one million dollars.");
	printf("\n THE TRIBE HAS EATEN....este...SPOKEN.\n");

}



void *savage (void *arg)
{	
	int iSid = (int) arg;

	pthread_mutex_lock(&lEnter);

		pthread_mutex_lock(&lPot);
		printf("\nPot: %d", iPot);
		if (iPot == 0)
		{ 
		  pthread_mutex_unlock(&lPot);
		  pthread_mutex_lock(&lCall);
		  	iCall = 1;//call the cook!
		  pthread_mutex_unlock(&lCall);
		  /*while (iCall = 1)
			sleep(1); //sleep until cook refills
		  */sleep(3);
		}
		else
		  pthread_mutex_unlock(&lPot);
		
		pthread_mutex_lock(&lArrive);
			iNumArrive--;
		pthread_mutex_unlock(&lArrive);
		pthread_mutex_lock(&lPot);
			iPot--;
		pthread_mutex_unlock(&lPot);		

	pthread_mutex_unlock(&lEnter);

	printf("\nSavage %d eats!", iSid);

}


void *cook (void *arg)
{
	do
	{
		pthread_mutex_unlock(&lArrive);
		pthread_mutex_lock(&lPot);
		pthread_mutex_lock(&lCall);
		if ((iPot == 0) && (iCall == 1))
		{
		  iPot = 2;
		  iCall = 0;
		  printf("\nCook refills!");
		}		
		pthread_mutex_unlock(&lCall);
		pthread_mutex_unlock(&lPot);
		pthread_mutex_lock(&lArrive);
	}while (iNumArrive > 0);

	pthread_mutex_unlock(&lArrive);

}
		

    Source: geocities.com/heero_9