Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b0f17ca8598d21faedfcdfdb7143be0397bb0213
[simgrid.git] / teshsuite / mc / mcmini / barber_shop_ok.c
1 #ifdef _REENTRANT
2 #undef _REENTRANT
3 #endif
4 #define _REENTRANT
5
6 #include <pthread.h>
7 #include <semaphore.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 // The maximum number of customer threads.
13 #define MAX_CUSTOMERS 25
14
15 // Define the semaphores.
16
17 // waitingRoom Limits the # of customers allowed
18 // to enter the waiting room at one time.
19 sem_t waitingRoom;
20
21 // barberChair ensures mutually exclusive access to
22 // the barber chair.
23 sem_t barberChair;
24
25 // barberPillow is used to allow the barber to sleep
26 // until a customer arrives.
27 sem_t barberPillow;
28
29 // seatBelt is used to make the customer to wait until
30 // the barber is done cutting his/her hair.
31 sem_t seatBelt;
32
33 // Flag to stop the barber thread when all customers
34 // have been serviced.
35 int allDone = 0;
36 int DEBUG   = 0;
37
38 static void randwait(int secs)
39 {
40   int len;
41
42   // Generate a random number...
43   len = (int)((drand48() * secs) + 1);
44   sleep(len);
45 }
46
47 static void* customer(void* number)
48 {
49   int num = *(int*)number;
50
51   // Leave for the shop and take some random amount of
52   // time to arrive.
53   if (DEBUG)
54     printf("Customer %d leaving for barber shop.\n", num);
55   randwait(5);
56   if (DEBUG)
57     printf("Customer %d arrived at barber shop.\n", num);
58
59   // Wait for space to open up in the waiting room...
60   sem_wait(&waitingRoom);
61   if (DEBUG)
62     printf("Customer %d entering waiting room.\n", num);
63
64   // Wait for the barber chair to become free.
65   sem_wait(&barberChair);
66
67   // The chair is free so give up your spot in the
68   // waiting room.
69   sem_post(&waitingRoom);
70
71   // Wake up the barber...
72   if (DEBUG)
73     printf("Customer %d waking the barber.\n", num);
74   sem_post(&barberPillow);
75
76   // Wait for the barber to finish cutting your hair.
77   sem_wait(&seatBelt);
78
79   // Give up the chair.
80   sem_post(&barberChair);
81   if (DEBUG)
82     printf("Customer %d leaving barber shop.\n", num);
83   return NULL;
84 }
85
86 static void* barber(void* junk)
87 {
88   // While there are still customers to be serviced...
89   // Our barber is omnicient and can tell if there are
90   // customers still on the way to his shop.
91   while (!allDone) {
92
93     // Sleep until someone arrives and wakes you..
94     if (DEBUG)
95       printf("The barber is sleeping\n");
96     sem_wait(&barberPillow);
97
98     // Skip this stuff at the end...
99     if (!allDone) {
100
101       // Take a random amount of time to cut the
102       // customer's hair.
103       if (DEBUG)
104         printf("The barber is cutting hair\n");
105       randwait(3);
106       if (DEBUG)
107         printf("The barber has finished cutting hair.\n");
108
109       // Release the customer when done cutting...
110       sem_post(&seatBelt);
111     } else {
112       if (DEBUG)
113         printf("The barber is going home for the day.\n");
114     }
115   }
116   return NULL;
117 }
118
119 int main(int argc, char* argv[])
120 {
121   pthread_t btid;
122   pthread_t tid[MAX_CUSTOMERS];
123   long RandSeed;
124   int i, numCustomers, numChairs;
125   int Number[MAX_CUSTOMERS];
126
127   // Check to make sure there are the right number of
128   // command line arguments.
129   if (argc != 5) {
130     printf("Use: SleepBarber <Num Customers> <Num Chairs> <rand seed> <DEBUG>\n");
131     exit(-1);
132   }
133
134   // Get the command line arguments and convert them
135   // into integers.
136   numCustomers = atoi(argv[1]);
137   numChairs    = atoi(argv[2]);
138   RandSeed     = atol(argv[3]);
139   DEBUG        = atoi(argv[4]);
140
141   // Make sure the number of threads is less than the number of
142   // customers we can support.
143   if (numCustomers > MAX_CUSTOMERS) {
144     printf("The maximum number of Customers is %d.\n", MAX_CUSTOMERS);
145     exit(-1);
146   }
147
148   printf("\nSleepBarber.c\n\n");
149   printf("A solution to the sleeping barber problem using semaphores.\n");
150
151   // Initialize the random number generator with a new seed.
152   srand48(RandSeed);
153
154   // Initialize the numbers array.
155   for (i = 0; i < MAX_CUSTOMERS; i++) {
156     Number[i] = i;
157   }
158
159   // Initialize the semaphores with initial values...
160   sem_init(&waitingRoom, 0, numChairs);
161   sem_init(&barberChair, 0, 1);
162   sem_init(&barberPillow, 0, 0);
163   sem_init(&seatBelt, 0, 0);
164
165   // Create the barber.
166   pthread_create(&btid, NULL, barber, NULL);
167
168   // Create the customers.
169   for (i = 0; i < numCustomers; i++) {
170     pthread_create(&tid[i], NULL, customer, (void*)&Number[i]);
171   }
172
173   // Join each of the threads to wait for them to finish.
174   for (i = 0; i < numCustomers; i++) {
175     pthread_join(tid[i], NULL);
176   }
177
178   // When all of the customers are finished, kill the
179   // barber thread.
180   allDone = 1;
181   sem_post(&barberPillow); // Wake the barber so he will exit.
182   pthread_join(btid, NULL);
183 }