1 /* linux-dp.c --- dining philosophers, on LinuxThreads
2 Jim Blandy <jimb@cygnus.com> --- March 1999 */
4 /* It's okay to edit this file and shift line numbers around. The
5 tests use gdb_get_line_number to find source locations, so they
6 don't depend on having certain line numbers in certain places. */
13 #include <sys/types.h>
15 /* The number of philosophers at the table. */
19 If you want to lock a mutex M, all the mutexes you have locked
20 already must appear before M on this list.
25 fork_mutex[num_philosophers - 1]
30 /* You must hold this mutex while writing to stdout. */
31 pthread_mutex_t stdout_mutex
;
33 /* You must hold this mutex while calling any of the random number
34 generation routines. */
35 pthread_mutex_t random_mutex
;
37 /* array of mutexes, one for each fork; fork_mutex[i] is to the left
38 of philosopher i. A philosopher is holding fork i iff his/her
39 thread has locked fork_mutex[i]. */
40 pthread_mutex_t
*fork_mutex
;
42 /* array of threads, one representing each philosopher. */
43 pthread_t
*philosophers
;
52 fprintf (stderr
, "out of memory\n");
60 shared_printf (char *format
, ...)
64 va_start (ap
, format
);
65 pthread_mutex_lock (&stdout_mutex
);
67 pthread_mutex_unlock (&stdout_mutex
);
74 static unsigned int seed
;
77 pthread_mutex_lock (&random_mutex
);
78 result
= rand_r (&seed
);
79 pthread_mutex_unlock (&random_mutex
);
84 my_usleep (long usecs
)
86 struct timeval timeout
;
88 timeout
.tv_sec
= usecs
/ 1000000;
89 timeout
.tv_usec
= usecs
% 1000000;
91 select (0, 0, 0, 0, &timeout
);
97 my_usleep ((shared_random () % 2000) * 100);
101 print_philosopher (int n
, char left
, char right
)
105 shared_printf ("%*s%c %d %c\n", (n
* 4) + 2, "", left
, n
, right
);
109 philosopher (void *data
)
111 int n
= * (int *) data
;
113 print_philosopher (n
, '_', '_');
116 if (n
== num_philosophers
- 1)
119 /* The last philosopher is different. He goes for his right
120 fork first, so there is no cycle in the mutex graph. */
122 /* Grab the right fork. */
123 pthread_mutex_lock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
124 print_philosopher (n
, '_', '!');
127 /* Then grab the left fork. */
128 pthread_mutex_lock (&fork_mutex
[n
]);
129 print_philosopher (n
, '!', '!');
132 print_philosopher (n
, '_', '_');
133 pthread_mutex_unlock (&fork_mutex
[n
]);
134 pthread_mutex_unlock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
141 /* Grab the left fork. */
142 pthread_mutex_lock (&fork_mutex
[n
]);
143 print_philosopher (n
, '!', '_');
146 /* Then grab the right fork. */
147 pthread_mutex_lock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
148 print_philosopher (n
, '!', '!');
151 print_philosopher (n
, '_', '_');
152 pthread_mutex_unlock (&fork_mutex
[n
]);
153 pthread_mutex_unlock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
161 main (int argc
, char **argv
)
163 num_philosophers
= 5;
165 /* Set up the mutexes. */
167 pthread_mutexattr_t ma
;
170 pthread_mutexattr_init (&ma
);
171 pthread_mutex_init (&stdout_mutex
, &ma
);
172 pthread_mutex_init (&random_mutex
, &ma
);
173 fork_mutex
= xmalloc (num_philosophers
* sizeof (fork_mutex
[0]));
174 for (i
= 0; i
< num_philosophers
; i
++)
175 pthread_mutex_init (&fork_mutex
[i
], &ma
);
176 pthread_mutexattr_destroy (&ma
);
179 /* Set off the threads. */
182 int *numbers
= xmalloc (num_philosophers
* sizeof (*numbers
));
185 philosophers
= xmalloc (num_philosophers
* sizeof (*philosophers
));
187 pthread_attr_init (&ta
);
189 for (i
= 0; i
< num_philosophers
; i
++)
192 /* linuxthreads.exp: create philosopher */
193 pthread_create (&philosophers
[i
], &ta
, philosopher
, &numbers
[i
]);
196 pthread_attr_destroy (&ta
);
199 /* linuxthreads.exp: info threads 2 */
202 /* Drink yourself into oblivion. */