1b411202f9ff33a587558e2e836626bc7eb9db183sewardj
2b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <pthread.h>
3b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdlib.h>
4b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <unistd.h>
546daf0d598c38c9251964712d894f0fcd3cc4143philippe#include <assert.h>
6b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* Naive dining philosophers with inconsistent lock acquisition
7b411202f9ff33a587558e2e836626bc7eb9db183sewardj   ordering. */
8b411202f9ff33a587558e2e836626bc7eb9db183sewardj
9b411202f9ff33a587558e2e836626bc7eb9db183sewardjstatic pthread_t phil[5];
1046daf0d598c38c9251964712d894f0fcd3cc4143philippestatic struct {
1146daf0d598c38c9251964712d894f0fcd3cc4143philippe   pthread_mutex_t m;
1246daf0d598c38c9251964712d894f0fcd3cc4143philippe   char pad[120 - sizeof(pthread_mutex_t)];
1346daf0d598c38c9251964712d894f0fcd3cc4143philippe} chop[5];
14b411202f9ff33a587558e2e836626bc7eb9db183sewardj
15b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* dine ( void* arg )
16b411202f9ff33a587558e2e836626bc7eb9db183sewardj{
17b411202f9ff33a587558e2e836626bc7eb9db183sewardj   int i;
18b411202f9ff33a587558e2e836626bc7eb9db183sewardj   long left = (long)arg;
19b411202f9ff33a587558e2e836626bc7eb9db183sewardj   long right = (left + 1) % 5;
20b411202f9ff33a587558e2e836626bc7eb9db183sewardj   for (i = 0; i < 1000/*arbitrary*/; i++) {
2146daf0d598c38c9251964712d894f0fcd3cc4143philippe      pthread_mutex_lock(&chop[left].m);
2246daf0d598c38c9251964712d894f0fcd3cc4143philippe      pthread_mutex_lock(&chop[right].m);
23b411202f9ff33a587558e2e836626bc7eb9db183sewardj      /* eating */
2446daf0d598c38c9251964712d894f0fcd3cc4143philippe      pthread_mutex_unlock(&chop[left].m);
2546daf0d598c38c9251964712d894f0fcd3cc4143philippe      pthread_mutex_unlock(&chop[right].m);
26b411202f9ff33a587558e2e836626bc7eb9db183sewardj   }
27b411202f9ff33a587558e2e836626bc7eb9db183sewardj   return NULL;
28b411202f9ff33a587558e2e836626bc7eb9db183sewardj}
29b411202f9ff33a587558e2e836626bc7eb9db183sewardj
30b411202f9ff33a587558e2e836626bc7eb9db183sewardjint main ( void )
31b411202f9ff33a587558e2e836626bc7eb9db183sewardj{
32b411202f9ff33a587558e2e836626bc7eb9db183sewardj   long i;
3346daf0d598c38c9251964712d894f0fcd3cc4143philippe   assert(sizeof(pthread_mutex_t) <= 120);
3446daf0d598c38c9251964712d894f0fcd3cc4143philippe
35b411202f9ff33a587558e2e836626bc7eb9db183sewardj   for (i = 0; i < 5; i++)
3646daf0d598c38c9251964712d894f0fcd3cc4143philippe      pthread_mutex_init( &chop[i].m, NULL);
37b411202f9ff33a587558e2e836626bc7eb9db183sewardj
38b411202f9ff33a587558e2e836626bc7eb9db183sewardj   for (i = 0; i < 5; i++)
39b411202f9ff33a587558e2e836626bc7eb9db183sewardj      pthread_create(&phil[i], NULL, dine, (void*)i );
40b411202f9ff33a587558e2e836626bc7eb9db183sewardj
41b411202f9ff33a587558e2e836626bc7eb9db183sewardj   sleep(1);
42b411202f9ff33a587558e2e836626bc7eb9db183sewardj
43b411202f9ff33a587558e2e836626bc7eb9db183sewardj   for (i = 0; i < 5; i++)
44b411202f9ff33a587558e2e836626bc7eb9db183sewardj      pthread_join(phil[i], NULL);
45b411202f9ff33a587558e2e836626bc7eb9db183sewardj
46b411202f9ff33a587558e2e836626bc7eb9db183sewardj   return 0;
47b411202f9ff33a587558e2e836626bc7eb9db183sewardj}
48