• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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