1 /*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * Created by: crystal.xiong REMOVE-THIS AT intel DOT com
4 * This file is licensed under the GPL license. For the full content
5 * of this license, see the COPYING file at the top level of this
6 * source tree.
7 *
8 * Test the well-known philosophy problem.
9 *
10 */
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <stdlib.h>
15 #include <sys/wait.h>
16 #include <sys/mman.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <semaphore.h>
20 #include <pthread.h>
21
22 #include "posixtest.h"
23
24 #define PH_NUM 5
25 #define LOOP_NUM 20
26 #define thinking 0
27 #define hungry 1
28 #define eating 2
29
30 sem_t ph[PH_NUM];
31 sem_t lock;
32
33 int state[PH_NUM];
34
think(int ID)35 int think(int ID)
36 {
37 printf("Philosoper [%d] is thinking... \n", ID);
38 return 0;
39 }
40
eat(int ID)41 int eat(int ID)
42 {
43 printf("Philosoper [%d] is eating... \n", ID);
44 return 0;
45 }
46
test(int ID)47 int test(int ID)
48 {
49 int preID = 0, postID = 0;
50 if ((ID - 1) < 0)
51 preID = PH_NUM + (ID - 1);
52 else
53 preID = (ID - 1) % PH_NUM;
54
55 if ((ID + 1) >= PH_NUM)
56 postID = ID + 1 - PH_NUM;
57 else
58 postID = (ID + 1) % PH_NUM;
59
60 if ((state[ID] == hungry) && (state[preID] != eating)
61 && (state[postID] != eating)) {
62 state[ID] = eating;
63 sem_post(&ph[ID]);
64 }
65 return 0;
66
67 }
68
philosopher(void * ID)69 int philosopher(void *ID)
70 {
71 int PhID = *(int *)ID;
72 int prePH, postPH;
73 int i;
74
75 for (i = 0; i < LOOP_NUM; i++) {
76 think(PhID);
77 sleep(1);
78 if (-1 == sem_wait(&lock)) {
79 perror("sem_wait didn't return success \n");
80 pthread_exit((void *)1);
81 }
82 state[PhID] = hungry;
83 test(PhID);
84 if (-1 == sem_post(&lock)) {
85 perror("sem_post didn't return success \n");
86 pthread_exit((void *)1);
87 }
88 if (-1 == sem_wait(&ph[PhID])) {
89 perror("sem_wait didn't return success \n");
90 pthread_exit((void *)1);
91 }
92 eat(PhID);
93 sleep(1);
94 if (-1 == sem_wait(&lock)) {
95 perror("sem_wait didn't return success \n");
96 pthread_exit((void *)1);
97 }
98 state[PhID] = thinking;
99 if ((PhID - 1) < 0)
100 prePH = PH_NUM + (PhID - 1);
101 else
102 prePH = (PhID - 1) % PH_NUM;
103 if ((PhID + 1) >= PH_NUM)
104 postPH = PhID + 1 - PH_NUM;
105 else
106 postPH = (PhID + 1) % PH_NUM;
107 test(prePH);
108 test(postPH);
109 if (-1 == sem_post(&lock)) {
110 perror("sem_post didn't return success \n");
111 pthread_exit((void *)1);
112 }
113 }
114 pthread_exit(NULL);
115 }
116
main(void)117 int main(void)
118 {
119 pthread_t phi[PH_NUM];
120 int PhID[PH_NUM];
121 int shared = 1;
122 int ph_value = 0;
123 int lock_value = 1;
124 int i;
125
126 #ifndef _POSIX_SEMAPHORES
127 printf("_POSIX_SEMAPHORES is not defined \n");
128 return PTS_UNRESOLVED;
129 #endif
130 for (i = 0; i < PH_NUM; i++) {
131 if (-1 == sem_init(&ph[i], shared, ph_value)) {
132 perror("sem_init didn't return success \n");
133 return PTS_UNRESOLVED;
134 }
135 state[i] = 0;
136 }
137 if (-1 == sem_init(&lock, shared, lock_value)) {
138 perror("sem_init didn't return success \n");
139 return PTS_UNRESOLVED;
140 }
141
142 for (i = 0; i < PH_NUM; i++) {
143 PhID[i] = i;
144 pthread_create(&phi[i], NULL, (void *)philosopher, &PhID[i]);
145 }
146
147 for (i = 0; i < PH_NUM; i++) {
148 pthread_join(phi[i], NULL);
149 }
150
151 for (i = 0; i < PH_NUM; i++) {
152 if (-1 == sem_destroy(&ph[i])) {
153 perror("sem_destroy didn't return success \n");
154 return PTS_UNRESOLVED;
155 }
156 }
157 if (-1 == sem_destroy(&lock)) {
158 perror("sem_destroy didn't return success \n");
159 return PTS_UNRESOLVED;
160 }
161 return PTS_PASS;
162 }
163