/*! \file
\brief Le problème des N philosophes 

L'évitement de l'interblocage est assuré par :
	- la numérotation des fourchettes
	- un ordre de prise des fourchettes droite et gauche dans le sens des numéros croissants et non dans le sens horaire ou anti-horaire.

\include philo.c
*/
#include "phil.h"
#include "psema.h"


#define NBphilo  7
PhilThread philosophe[NBphilo];
PhilSemaphore fourchette[NBphilo];





 void* codephilo(void * x)
{
	int j,k;
	int i = (int)x;
	PhilPrintf(" \n philo %d numero %d demarre \n ",  PhilThreadCurrent(),i);
	for( j=0;j<100;j++){ 
  	PhilPrintf(" \n philo %d pense %d éme fois \n ", i,j);
		for(k=0;k<1000000;k++); /* ça pense ..*/
		PhilThreadYield(); 
  	PhilPrintf(" \n philo %d veut manger %d éme fois \n ", i,j);
		if(i<(NBphilo-1)){ /* un droitier */
			PhilSemaphoreP(&fourchette[i]);PhilSemaphoreP(&fourchette[i+1]);
			PhilPrintf(" \n philo droitier %d mange %d éme fois \n ", i,j);
			for( k=0;k<1000000;k++); /* ça mange ..*/
			PhilThreadYield();
			PhilSemaphoreV(&fourchette[i]);PhilSemaphoreV(&fourchette[i+1]);
		}else{ /* le gaucher */
			PhilSemaphoreP(&fourchette[0]);PhilSemaphoreP(&fourchette[NBphilo-1]);
			PhilPrintf(" \n philo GAUCHER %d mange %d éme fois \n ", i,j);
			for( k=0;k<1000000;k++);/* ça mange ..*/
			PhilThreadYield();
			PhilSemaphoreV(&fourchette[0]);PhilSemaphoreV(&fourchette[NBphilo-1]);
		}
  }
	PhilPrintf(" \n philo  %d ADIEU \n ", i);
	return (void*) 0;
}




int main ( int argc, char** argv)
{
	int i; 
	printf(" C'est parti \n");
	PhilInitialize();
  for( i=0;i<NBphilo;i++)
  {
    PhilSemaphoreInit(&fourchette[i],1);
    PhilPrintf("Initialisation fourchette[%d]]  \n ",  i);
  }
	for( i=0;i<NBphilo;i++)
  {
   philosophe[i]= PhilThreadCreate(0, 0,20000,codephilo,(void*)i);
   PhilPrintf("Lancement philosophe[%d]]  \n ",  i);
  }
	PhilPrintf("philodsophes lancés !!!!  \n ");
	for(i=0;i<NBphilo;i++)PhilThreadJoin(philosophe[i], 0);
  PhilPrintf("philosophes repus !!!!  \n ");
	PhilWaitTerminate();
	printf(" C'est termine \n");
 	return 0;
}




