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 35 int think(int ID) 36 { 37 printf("Philosoper [%d] is thinking... \n", ID); 38 return 0; 39 } 40 41 int eat(int ID) 42 { 43 printf("Philosoper [%d] is eating... \n", ID); 44 return 0; 45 } 46 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 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 117 int main(int argc, char *argv[]) 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