forked from remzi-arpacidusseau/ostep-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dining_philosophers_no_deadlock.c
90 lines (73 loc) · 1.47 KB
/
dining_philosophers_no_deadlock.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "common.h"
#include "common_threads.h"
#ifdef linux
#include <semaphore.h>
#elif __APPLE__
#include "zemaphore.h"
#endif
typedef struct {
int num_loops;
int thread_id;
} arg_t;
sem_t forks[5];
int left(int p) {
return p;
}
int right(int p) {
return (p + 1) % 5;
}
void get_forks(int p) {
if (p == 4) {
Sem_wait(&forks[right(p)]);
Sem_wait(&forks[left(p)]);
} else {
Sem_wait(&forks[left(p)]);
Sem_wait(&forks[right(p)]);
}
}
void put_forks(int p) {
Sem_post(&forks[left(p)]);
Sem_post(&forks[right(p)]);
}
void think() {
return;
}
void eat() {
return;
}
void *philosopher(void *arg) {
arg_t *args = (arg_t *) arg;
int p = args->thread_id;
int i;
for (i = 0; i < args->num_loops; i++) {
think();
get_forks(p);
eat();
put_forks(p);
}
return NULL;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: dining_philosophers <num_loops>\n");
exit(1);
}
printf("dining: started\n");
int i;
for (i = 0; i < 5; i++)
Sem_init(&forks[i], 1);
pthread_t p[5];
arg_t a[5];
for (i = 0; i < 5; i++) {
a[i].num_loops = atoi(argv[1]);
a[i].thread_id = i;
Pthread_create(&p[i], NULL, philosopher, &a[i]);
}
for (i = 0; i < 5; i++)
Pthread_join(p[i], NULL);
printf("dining: finished\n");
return 0;
}