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 static sem_t customer;
29 static sem_t barber;
30 static sem_t lock;
31 static sem_t print;
32
33 static 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
mdelay(unsigned msecs)45 static 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
barbers(void * unused PTS_ATTRIBUTE_UNUSED)53 static void *barbers(void *unused PTS_ATTRIBUTE_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
customers(void * ID)95 static 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
main(void)138 int main(void)
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