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 sleeping barber 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 <pthread.h> 20 #include <semaphore.h> 21 #include <time.h> 22 23 #include "posixtest.h" 24 #define CHAIR_NUM 5 25 #define CUS_NUM 10 26 #define LOOP_NUM 30 27 28 sem_t customer; 29 sem_t barber; 30 sem_t lock; 31 sem_t print; 32 33 int waiting = 0; 34 35 #ifdef __GNUC__ 36 #define my_printf(x...) do { \ 37 sem_wait(&print); \ 38 printf(x); \ 39 sem_post(&print); \ 40 } while (0) 41 #else 42 #define my_printf printf 43 #endif 44 45 void mdelay(unsigned msecs) 46 { 47 struct timespec req; 48 req.tv_sec = msecs / 1000; 49 req.tv_nsec = (msecs % 1000) * 1000000; 50 nanosleep(&req, NULL); 51 } 52 53 void *barbers(void *unused) 54 { 55 int i; 56 for (i = 0; i < LOOP_NUM; i++) { 57 if (-1 == sem_wait(&lock)) { 58 perror("sem_wait(&lock) didn't return success"); 59 pthread_exit((void *)1); 60 } 61 if (waiting == 0) { 62 my_printf 63 ("There are no more customers waiting, barber will sleep.\n"); 64 } 65 if (-1 == sem_post(&lock)) { 66 perror("sem_post(&lock) didn't return success"); 67 pthread_exit((void *)1); 68 } 69 if (-1 == sem_wait(&customer)) { 70 perror("sem_wait(&customer) didn't return success"); 71 pthread_exit((void *)1); 72 } 73 if (-1 == sem_wait(&lock)) { 74 perror("sem_wait(&lock) didn't return success"); 75 pthread_exit((void *)1); 76 } 77 if (waiting >= 1) 78 waiting--; 79 my_printf 80 ("A customer sits in the barber's chair and get a hair cut. %d customers left waiting.\n", 81 waiting); 82 if (-1 == sem_post(&lock)) { 83 perror("sem_post(&lock) didn't return success"); 84 pthread_exit((void *)1); 85 } 86 if (-1 == sem_post(&barber)) { 87 perror("sem_post(&barber) didn't return success"); 88 pthread_exit((void *)1); 89 } 90 91 } 92 return NULL; 93 } 94 95 void *customers(void *ID) 96 { 97 int CusID; 98 CusID = *(int *)ID; 99 100 if (CusID == 8) 101 mdelay(10); 102 103 my_printf("customer %d enters the room.\n", CusID); 104 if (-1 == sem_wait(&lock)) { 105 perror("sem_wait(&lock) didn't return success"); 106 pthread_exit((void *)1); 107 } 108 if (waiting < CHAIR_NUM) { 109 waiting = waiting + 1; 110 if (-1 == sem_post(&customer)) { 111 perror("sem_post(&customer) didn't return success"); 112 pthread_exit((void *)1); 113 } 114 my_printf 115 ("Customer %d sits down, now %d customers are waiting.\n", 116 CusID, waiting); 117 if (-1 == sem_post(&lock)) { 118 perror("sem_post(&lock) didn't return success"); 119 pthread_exit((void *)1); 120 } 121 if (-1 == sem_wait(&barber)) { 122 perror("sem_wait(&barber) didn't return success"); 123 pthread_exit((void *)1); 124 } 125 my_printf("Customer %d leaves with nice hair.\n", CusID); 126 } else { 127 my_printf 128 ("No chairs available, customer %d leaves without a haircut.\n", 129 CusID); 130 if (-1 == sem_post(&lock)) { 131 perror("sem_post(&lock) didn't return success"); 132 pthread_exit((void *)1); 133 } 134 } 135 return NULL; 136 } 137 138 int main(int argc, char *argv[]) 139 { 140 pthread_t bar, cus[CUS_NUM]; 141 int shared = 0; 142 int barber_value = 0; 143 int customer_value = 0; 144 int lock_value = 1; 145 int i, ID[CUS_NUM]; 146 147 if (-1 == sem_init(&print, shared, 1)) { 148 perror("sem_init(&print) didn't return success"); 149 return PTS_UNRESOLVED; 150 } 151 #ifndef _POSIX_SEMAPHORES 152 my_printf("_POSIX_SEMAPHORES is not defined\n"); 153 return PTS_UNRESOLVED; 154 #endif 155 if (-1 == sem_init(&customer, shared, customer_value)) { 156 perror("sem_init(&customer) didn't return success"); 157 return PTS_UNRESOLVED; 158 } 159 if (-1 == sem_init(&barber, shared, barber_value)) { 160 perror("sem_init(&barber) didn't return success"); 161 return PTS_UNRESOLVED; 162 } 163 if (-1 == sem_init(&lock, shared, lock_value)) { 164 perror("sem_init(&lock) didn't return success"); 165 return PTS_UNRESOLVED; 166 } 167 for (i = 0; i < CUS_NUM; i++) { 168 ID[i] = i; 169 pthread_create(&cus[i], NULL, customers, (void *)&ID[i]); 170 } 171 pthread_create(&bar, NULL, barbers, NULL); 172 for (i = 0; i < CUS_NUM; i++) 173 pthread_join(cus[i], NULL); 174 175 return PTS_PASS; 176 } 177