Oracle® Solaris Studio 12.4: Thread Analyzer User's Guide

Exit Print View

Updated: December 2014
 
 

Source Code Listing for din_philo.c

The source code for din_philo.c is shown below:

  1  /*
  2   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All Rights Reserved.
  3   * @(#)din_philo.c 1.4 (Oracle) 10/03/26
  4   */
  5
  6  #include <pthread.h>
  7  #include <stdio.h>
  8  #include <unistd.h>
  9  #include <stdlib.h>
 10  #include <errno.h>
 11  #include <assert.h>
 12
 13  #define PHILOS 5
 14  #define DELAY 5000
 15  #define FOOD 100
 16
 17  void *philosopher (void *id);
 18  void grab_chopstick (int,
 19                       int,
 20                       char *);
 21  void down_chopsticks (int,
 22                        int);
 23  int food_on_table ();
 24
 25  pthread_mutex_t chopstick[PHILOS];
 26  pthread_t philo[PHILOS];
 27  pthread_mutex_t food_lock;
 28  int sleep_seconds = 0;
 29
 30
 31  int
 32  main (int argn,
 33        char **argv)
 34  {
 35      int i;
 36
 37      if (argn == 2)
 38          sleep_seconds = atoi (argv[1]);
 39
 40      pthread_mutex_init (&food_lock, NULL);
 41      for (i = 0; i < PHILOS; i++)
 42          pthread_mutex_init (&chopstick[i], NULL);
 43      for (i = 0; i < PHILOS; i++)
 44          pthread_create (&philo[i], NULL, philosopher, (void *)i);
 45      for (i = 0; i < PHILOS; i++)
 46          pthread_join (philo[i], NULL);
 47      return 0;
 48  }
 49
 50  void *
 51  philosopher (void *num)
 52  {
 53      int id;
 54      int i, left_chopstick, right_chopstick, f;
 55
 56      id = (int)num;
 57      printf ("Philosopher %d is done thinking and now ready to eat.\n", id);
 58      right_chopstick = id;
 59      left_chopstick = id + 1;
 60
 61      /* Wrap around the chopsticks. */
 62      if (left_chopstick == PHILOS)
 63          left_chopstick = 0;
 64
 65      while (f = food_on_table ()) {
 66
 67          /* Thanks to philosophers #1 who would like to take a nap
 68           * before picking up the chopsticks, the other philosophers
 69           * may be able to eat their dishes and not deadlock.
 70           */
 71          if (id == 1)
 72              sleep (sleep_seconds);
 73
 74          grab_chopstick (id, right_chopstick, "right ");
 75          grab_chopstick (id, left_chopstick, "left");
 76
 77          printf ("Philosopher %d: eating.\n", id);
 78          usleep (DELAY * (FOOD - f + 1));
 79          down_chopsticks (left_chopstick, right_chopstick);
 80      }
 81
 82      printf ("Philosopher %d is done eating.\n", id);
 83      return (NULL);
 84  }
 85
 86  int
 87  food_on_table ()
 88  {
 89      static int food = FOOD;
 90      int myfood;
 91
 92      pthread_mutex_lock (&food_lock);
 93      if (food > 0) {
 94          food--;
 95      }
 96      myfood = food;
 97      pthread_mutex_unlock (&food_lock);
 98      return myfood;
 99  }
100
101  void
102  grab_chopstick (int phil,
103                  int c,
104                  char *hand)
105  {
106      pthread_mutex_lock (&chopstick[c]);
107      printf ("Philosopher %d: got %s chopstick %d\n", phil, hand, c);
108  }
109
110  void
111  down_chopsticks (int c1,
112                   int c2)
113  {
114      pthread_mutex_unlock (&chopstick[c1]);
115      pthread_mutex_unlock (&chopstick[c2]);
116  }