I have to create my own semaphores in the dining philosopher's problem. For some reason the philosophers are picking up chopsticks that should not be getting picked up. Whats wrong with my code?
#define NUM_PHILS 5 /* Must be 5 */
#define MEAN_THINK_TIME 1000 /* avg think time in milliseconds */
#define MEAN_EAT_TIME 750 /* avg eat time in milliseconds */
int choosing[NUM_PHILS] = {0};
int numbering[NUM_PHILS] = {0};
float total_time_spent_waiting = 0.0;
int total_number_of_meals = 0;
int chopstick[NUM_PHILS];
int lexvalue(int a, int b, int c, int d)
{
if(a>c)
return 0;
else if(a<c)
return 1;
else if(b>d)
return 0;
else
return 1;
}
int max(int num[])
{
int m = 0;
int n;
for(n = 0; n<NUM_PHILS; n++)
{
if(num[n]>m)
m = num[n];
//printf("Max = %d\n",m);
}
return m;
}
void lock(int i)
{
choosing[i] = 1;
numbering[i] = max(numbering)+1;
choosing[i] = 0;
int j;
for(j=0; j<NUM_PHILS; j++)
{
if(j != i)
{
while(choosing[j]){;}
int result = lexvalue(numbering[j], j, numbering[i], i);
while((numbering[j]!=0) || (result == 0)){;}
}
}
}
void unlock(int i)
{
numbering[i] = 0;
}
wait(int s)
{
while(s>=0)
{
printf("In wait s = %d\n", s);
lock(s);
s = s - 1;
printf("s past lock = %d\n", s);
unlock(s);
}
}
signal(int s)
{
printf("In signal s = %d\n", s);
lock(s);
s = s + 1;
unlock(s);
}
//Print out what Philosopher has what chopstick
void Pickup_chopstick( int c, int n )
{
printf("Philosopher %d picked up chopstick %d...\n", n, c);
}
//Obtain chopsticks for a particular Philosopher
void Get_chopsticks( int n )
{
if ( n % 2 == 0 )
{
//Left then right
//semaphore_wait( chopstick[(n+1) % NUM_PHILS] );
//printf("before wait chopstick[(n+1) % NUM_PHILS] = %d\n", chopstick[(n+1) % NUM_PHILS]);
wait(chopstick[(n+1) % NUM_PHILS]);
//printf("after wait chopstick[(n+1) % NUM_PHILS] = %d\n", chopstick[(n+1) % NUM_PHILS]);
Pickup_chopstick( (n+1) % NUM_PHILS, n );
//semaphore_wait( chopstick[n] );
//printf("before wait chopstick[n] = %d\n", chopstick[n]);
wait(chopstick[n]);
//printf("after wait chopstick[n] = %d\n", chopstick[n]);
Pickup_chopstick( n, n );
}
else
{
//Right then left
//semaphore_wait( chopstick[n] );
//printf("before wait chopstick[n] = %d\n", chopstick[n]);
wait(chopstick[n]);
//printf("after wait chopstick[n] = %d\n", chopstick[n]);
Pickup_chopstick( n, n );
//semaphore_wait( chopstick[(n+1) % NUM_PHILS] );
//printf("before wait chopstick[(n+1) % NUM_PHILS] = %d\n", chopstick[(n+1) % NUM_PHILS]);
wait(chopstick[(n+1) % NUM_PHILS]);
//printf("after wait chopstick[(n+1) % NUM_PHILS] = %d\n", chopstick[(n+1) % NUM_PHILS]);
Pickup_chopstick( (n+1) % NUM_PHILS, n );
}
}
//Replace the chopsticks for a particular Philosopher
void Drop_chopsticks( int n )
{
int c;
c = n;
printf("Philosopher %d put down chopstick %d...\n", n, c);
//printf("before signal chopstick[n] = %d\n", chopstick[n]);
//semaphore_signal( chopstick[n] );
signal(chopstick[n]);
//printf("after signal chopstick[n] = %d\n", chopstick[n]);
c = (n+1)%NUM_PHILS;
printf("Philosopher %d put down chopstick %d...\n", n, c);
//printf("before signal chopstick[(n+1) % NUM_PHILS] = %d\n", chopstick[(n+1) % NUM_PHILS]);
//semaphore_signal( chopstick[(n+1) % NUM_PHILS] );
signal(chopstick[(n+1) % NUM_PHILS]);
//printf("after signal chopstick[(n+1) % NUM_PHILS] = %d\n", chopstick[(n+1) % NUM_PHILS]);
}
//Contols all actions for the Philosophers
void Philosopher( int *phil_data )
{
int time;
int eat_count = 0;
int total_hungry_time = 0;
int became_hungry_time;
int n = phil_data[0];
int duration = phil_data[1];
time = msecond();
while( msecond() - time < duration * 1000 )
{
//Philosopher is hungry
became_hungry_time = msecond();
printf("Philosopher %d is hungry...\n", n);
Get_chopsticks( n );
//Philosopher is eating
total_hungry_time += ( msecond() - became_hungry_time );
eat_count++;
printf("Philosopher %d is eating...", n);
printf( "(%d)\n", eat_count );
usleep( 1000L * random_int( MEAN_EAT_TIME ) );
Drop_chopsticks( n );
//Philosopher is thinking
printf("Philosopher %d is thinking...\n", n);
usleep( 1000L * random_int( MEAN_THINK_TIME ) );
}
//Philosopher is done with everything
printf("Philosopher %d is done...\n", n);
/* Update the shared variable database */
//semaphore_wait( mutex );
//wait(m);
//total_number_of_meals += eat_count;
//total_time_spent_waiting
+= ( total_hungry_time / 1000.0 );
//semaphore_signal( mutex );
//signal(m);
pthread_exit( NULL );
}
//Main Function
int main( int argc, char *argv[] )
{
pthread_t phil[NUM_PHILS];
int phil_data[NUM_PHILS][2];
int duration;
int i;
//duration = ( argc > 1 ? atoi( argv[1] ) : 10 );
duration = 1;
for ( i = 0; i < NUM_PHILS; i++ )
{
//create semaphore to protect chopsticks
chopstick[i] = 0;
printf("chopstick[i] = %d\n", chopstick[i]);
}
for ( i = 0; i < NUM_PHILS; i++ )
{
phil_data[i][0] = i;
phil_data[i][1] = duration;
if ( pthread_create( &phil[i], NULL, (void *(*)(void *)) &Philosopher,
&phil_data[i] ) != 0 ) {
fprintf( stderr, "cannot create thread for Philosopher %d\n", i );
exit( 1 );
}
}
for ( i = 0; i < NUM_PHILS; i++ )
{
pthread_join( phil[i], NULL );
}
printf( "Total meals served = %d\n", total_number_of_meals );
printf( "Average hungry time = %f\n",
total_time_spent_waiting / total_number_of_meals );
return 0;
}