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
);
76 pthread_mutex_lock (&random_mutex
);
78 pthread_mutex_unlock (&random_mutex
);
83 my_usleep (long usecs
)
85 struct timeval timeout
;
87 timeout
.tv_sec
= usecs
/ 1000000;
88 timeout
.tv_usec
= usecs
% 1000000;
90 select (0, 0, 0, 0, &timeout
);
96 my_usleep ((shared_random () % 2000) * 100);
100 print_philosopher (int n
, char left
, char right
)
104 shared_printf ("%*s%c %d %c\n", (n
* 4) + 2, "", left
, n
, right
);
108 philosopher (void *data
)
110 int n
= * (int *) data
;
112 print_philosopher (n
, '_', '_');
115 if (n
== num_philosophers
- 1)
118 /* The last philosopher is different. He goes for his right
119 fork first, so there is no cycle in the mutex graph. */
121 /* Grab the right fork. */
122 pthread_mutex_lock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
123 print_philosopher (n
, '_', '!');
126 /* Then grab the left fork. */
127 pthread_mutex_lock (&fork_mutex
[n
]);
128 print_philosopher (n
, '!', '!');
131 print_philosopher (n
, '_', '_');
132 pthread_mutex_unlock (&fork_mutex
[n
]);
133 pthread_mutex_unlock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
140 /* Grab the left fork. */
141 pthread_mutex_lock (&fork_mutex
[n
]);
142 print_philosopher (n
, '!', '_');
145 /* Then grab the right fork. */
146 pthread_mutex_lock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
147 print_philosopher (n
, '!', '!');
150 print_philosopher (n
, '_', '_');
151 pthread_mutex_unlock (&fork_mutex
[n
]);
152 pthread_mutex_unlock (&fork_mutex
[(n
+ 1) % num_philosophers
]);
160 main (int argc
, char **argv
)
162 num_philosophers
= 5;
164 /* Set up the mutexes. */
166 pthread_mutexattr_t ma
;
169 pthread_mutexattr_init (&ma
);
170 pthread_mutex_init (&stdout_mutex
, &ma
);
171 pthread_mutex_init (&random_mutex
, &ma
);
172 fork_mutex
= xmalloc (num_philosophers
* sizeof (fork_mutex
[0]));
173 for (i
= 0; i
< num_philosophers
; i
++)
174 pthread_mutex_init (&fork_mutex
[i
], &ma
);
175 pthread_mutexattr_destroy (&ma
);
178 /* Set off the threads. */
181 int *numbers
= xmalloc (num_philosophers
* sizeof (*numbers
));
184 philosophers
= xmalloc (num_philosophers
* sizeof (*philosophers
));
186 pthread_attr_init (&ta
);
188 for (i
= 0; i
< num_philosophers
; i
++)
191 /* linuxthreads.exp: create philosopher */
192 pthread_create (&philosophers
[i
], &ta
, philosopher
, &numbers
[i
]);
195 pthread_attr_destroy (&ta
);
198 /* linuxthreads.exp: info threads 2 */
201 /* Drink yourself into oblivion. */