Skip Navigation Links | |
Exit Print View | |
![]() |
Oracle Solaris Studio 12.3: Thread Analyzer User's Guide Oracle Solaris Studio 12.3 Information Library |
1. What is the Thread Analyzer and What Does It Do?
3.3 The Dining Philosophers Scenario
3.3.1 How the Philosophers Can Deadlock
3.3.2 Introducing a Sleep Time for Philosopher 1
3.4 How to Use the Thread Analyzer to Find Deadlocks
3.4.2 Create a Deadlock Detection Experiment
3.4.3 Examine the Deadlock Detection Experiment
3.4.3.1 Using Thread Analyzer to View the Deadlock Detection Experiment
3.4.3.2 Using er_print to View the Deadlock Detection Experiment
3.5 Understanding the Deadlock Experiment Results
3.5.1 Examining Runs That Deadlock
3.5.2 Examining Runs That Complete Despite Deadlock Potential
3.6 Fixing the Deadlocks and Understanding False Positives
3.6.1 Regulating the Philosophers With Tokens
3.6.1.1 A False Positive Report
3.6.2 An Alternative System of Tokens
You can download the source files used in this tutorial from the samples download area of the Oracle Solaris Studio developer portal.
After you download and unpack the sample files, you can find the samples in the SolarisStudioSampleApplications/ThreadAnalyzer directory. The samples are located in the din_philo subdirectory. The din_philo directory includes a Makefile and a DEMO file of instructions, but this tutorial does not follow those instructions or use the Makefile. Instead, you are instructed to execute commands individually.
To follow the tutorial, you can copy the din_philo.c file from the SolarisStudioSampleApplications/ThreadAnalyzer/din_philo directory to a different directory, or you can create your own file and copy the code from the following code listing.
The din_philo.c sample program which simulates the dining-philosophers problem is a C program that uses POSIX threads. The program can exhibit both potential and actual deadlocks.
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 }