/* * Philosopher code */ static void *dp_thread(void *arg) { int think_rnd; int eat_rnd; int i; philosopher *me; me = (philosopher *) arg; me->tid = gettid(); while (!stop) { think_rnd = (rand() % 10000); eat_rnd = (rand() % 10000); /* * Think a random number of thoughts before getting hungry */ for (i = 0; i < think_rnd; i++){ think_one_thought(); } /* * Grab both chopsticks */ #if DEADLOCK /* * This order results in deadlock */ pthread_mutex_lock(left_chop(me)); pthread_mutex_lock(right_chop(me)); #else /* * This order avoids deadlock */ if(me->id % 2 == 0) { pthread_mutex_lock(left_chop(me)); pthread_mutex_lock(right_chop(me)); } else { pthread_mutex_lock(right_chop(me)); pthread_mutex_lock(left_chop(me)); } #endif /* * Eat some random amount of food */ for (i = 0; i < eat_rnd; i++){ eat_one_mouthful(); } /* * Release both chopsticks */ pthread_mutex_unlock(right_chop(me)); pthread_mutex_unlock(left_chop(me)); } return NULL; }
/* * Philosopher code which makes each philosopher eat and think for a * random period of time. */ static void *dp_thread(void *arg) { int eat_rnd; int i; int id; philosopher *me; int think_rnd; me = (philosopher *) arg; id = me->id; /* * While the gobal Stop flag is not set, keep thinking and eating * like a good Philosopher. */ while (!Stop) { /* * Determine how long to think and eat in this cycle. Limit the * values to defined maximum values. */ think_rnd = (rand() % MAX_PHIL_THINK_PERIOD); eat_rnd = (rand() % MAX_PHIL_EAT_PERIOD); /* * Think a random number of thoughts before getting hungry. this * is a loop with a lot of overhead, since we call a subroutine * for each thought. That is a feature, not a bug, in this case as * we want each thought to be several machine instructions. */ for (i = 0; i < think_rnd; i++){ think_one_thought(); } /* * Grab both chopsticks: ASYMMETRIC and WAITER SOLUTION */ pthread_mutex_lock(left_chop(me)); pthread_mutex_lock(right_chop(me)); /* * Eat some random amount of food. Again, this involves a * subroutine call for each mouthful, which is a feature, not a * bug. */ for (i = 0; i < eat_rnd; i++){ eat_one_mouthful(); } /* * Release both chopsticks: WAITER SOLUTION */ pthread_mutex_unlock(right_chop(me)); pthread_mutex_unlock(left_chop(me)); /* * Update my progress in current session and for all time. */ me->prog++; me->prog_total++; } /* * Philosopher thread finished, so rejoin parent */ return NULL; }