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 <getopt.h> 19#include <errno.h> 20#include <semaphore.h> 21#include <pthread.h> 22 23#include "posixtest.h" 24 25#define PH_NUM 5 26#define LOOP_NUM 20 27#define thinking 0 28#define hungry 1 29#define eating 2 30 31sem_t ph[PH_NUM]; 32sem_t lock; 33 34int state[PH_NUM]; 35 36int think(int ID) 37{ 38 printf("Philosoper [%d] is thinking... \n", ID); 39 return 0; 40} 41int eat(int ID) 42{ 43 printf("Philosoper [%d] is eating... \n", ID); 44 return 0; 45} 46int test(int ID) 47{ 48 int preID = 0, postID = 0; 49 if ((ID - 1) < 0) 50 preID = PH_NUM + (ID - 1); 51 else 52 preID = (ID - 1)%PH_NUM; 53 54 if ((ID + 1) >= PH_NUM) 55 postID = ID + 1 - PH_NUM; 56 else 57 postID = (ID + 1)%PH_NUM; 58 59 if ((state[ID] == hungry)&&(state[preID]!= eating)&&(state[postID] != eating)) { 60 state[ID] = eating; 61 sem_post(&ph[ID]); 62 } 63 return 0; 64 65} 66int philosopher(void *ID) 67{ 68 int PhID = *(int *)ID; 69 int prePH, postPH; 70 int i; 71 72 for (i = 0; i < LOOP_NUM; i++) { 73 think(PhID); 74 sleep(1); 75 if ( -1 == sem_wait(&lock)) { 76 perror("sem_wait didn't return success \n"); 77 pthread_exit((void *)1); 78 } 79 state[PhID] = hungry; 80 test(PhID); 81 if ( -1 == sem_post(&lock)) { 82 perror("sem_post didn't return success \n"); 83 pthread_exit((void *)1); 84 } 85 if ( -1 == sem_wait(&ph[PhID])) { 86 perror("sem_wait didn't return success \n"); 87 pthread_exit((void *)1); 88 } 89 eat(PhID); 90 sleep(1); 91 if ( -1 == sem_wait(&lock)) { 92 perror("sem_wait didn't return success \n"); 93 pthread_exit((void *)1); 94 } 95 state[PhID] = thinking; 96 if ((PhID - 1) < 0) 97 prePH = PH_NUM + (PhID - 1); 98 else 99 prePH = (PhID - 1)%PH_NUM; 100 if ((PhID + 1) >= PH_NUM) 101 postPH = PhID + 1 - PH_NUM; 102 else 103 postPH = (PhID + 1)%PH_NUM; 104 test(prePH); 105 test(postPH); 106 if ( -1 == sem_post(&lock)) { 107 perror("sem_post didn't return success \n"); 108 pthread_exit((void *)1); 109 } 110 } 111 pthread_exit((void *) 0); 112} 113 114int main(int argc, char *argv[]) 115{ 116 pthread_t phi[PH_NUM]; 117 int PhID[PH_NUM]; 118 int shared = 1; 119 int ph_value = 0; 120 int lock_value = 1; 121 int i ; 122 123#ifndef _POSIX_SEMAPHORES 124 printf("_POSIX_SEMAPHORES is not defined \n"); 125 return PTS_UNRESOLVED; 126#endif 127 for (i = 0; i < PH_NUM; i++) { 128 if (-1 == sem_init(&ph[i], shared, ph_value)) { 129 perror("sem_init didn't return success \n"); 130 return PTS_UNRESOLVED; 131 } 132 state[i] = 0; 133 } 134 if (-1 == sem_init(&lock, shared, lock_value)) { 135 perror("sem_init didn't return success \n"); 136 return PTS_UNRESOLVED; 137 } 138 139 for (i = 0; i< PH_NUM; i++) { 140 PhID[i] = i; 141 pthread_create(&phi[i], NULL, (void *)philosopher, &PhID[i]); 142 } 143 144 for (i = 0; i< PH_NUM; i++) { 145 pthread_join(phi[i], NULL); 146 } 147 148 for (i = 0; i< PH_NUM; i++) { 149 if (-1 == sem_destroy(&ph[i])) { 150 perror("sem_destroy didn't return success \n"); 151 return PTS_UNRESOLVED; 152 } 153 } 154 if (-1 == sem_destroy(&lock)) { 155 perror("sem_destroy didn't return success \n"); 156 return PTS_UNRESOLVED; 157 } 158 return PTS_PASS; 159} 160