Home | History | Annotate | Download | only in semaphores
      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