Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add more tests from McMini
[simgrid.git] / teshsuite / mc / mcmini / philosophers_semaphores_deadlock.c
1 // Dining philosophers solution with semaphores
2
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <pthread.h>
6 #include <semaphore.h>
7 #include <stdlib.h>
8
9 struct forks {
10     int philosopher;
11     pthread_mutex_t *left_fork;
12     pthread_mutex_t *right_fork;
13     sem_t* sem_dining;
14     int DEBUG;
15 } *forks;
16
17 static void * philosopher_doit(void *forks_arg) {
18     struct forks *forks = forks_arg;
19     sem_wait(forks->sem_dining);
20     pthread_mutex_lock(forks->left_fork);
21     pthread_mutex_lock(forks->right_fork);
22
23     if(forks->DEBUG) printf("Philosopher %d just ate.\n", forks->philosopher);
24     
25     pthread_mutex_unlock(forks->left_fork);
26     pthread_mutex_unlock(forks->right_fork);
27     sem_post(forks->sem_dining);
28     return NULL;
29 }
30
31 int main(int argc, char* argv[]) {
32     if(argc != 3){
33         printf("Usage: %s NUM_PHILOSOPHERS DEBUG\n", argv[0]);
34         return 1;
35     }
36
37     int NUM_THREADS = atoi(argv[1]);
38     int DEBUG = atoi(argv[2]);
39
40     pthread_t thread[NUM_THREADS];
41     pthread_mutex_t mutex_resource[NUM_THREADS];
42     sem_t sem_dining;
43     sem_init(&sem_dining, 0, NUM_THREADS);
44
45     forks = malloc(NUM_THREADS * sizeof(struct forks));
46
47     int i;
48     for (i = 0; i < NUM_THREADS; i++) {
49         pthread_mutex_init(&mutex_resource[i], NULL);
50         forks[i] = (struct forks){i,
51                                   &mutex_resource[i],
52                                   &mutex_resource[(i+1) % NUM_THREADS],
53                                   &sem_dining,
54                                   DEBUG};
55     }
56
57     for (i = 0; i < NUM_THREADS; i++) {
58         pthread_create(&thread[i], NULL, &philosopher_doit, &forks[i]);
59     }
60
61     for (i = 0; i < NUM_THREADS; i++) {
62         pthread_join(thread[i], NULL);
63     }
64
65     free(forks);
66     return 0;
67 }