Esempio n. 1
0
/*
 * 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;
}