-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShop.cpp
145 lines (117 loc) · 4.95 KB
/
Shop.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <iostream> // cout
#include <sstream> // stringstream
#include <string> // string
#include "Shop.h"
void Shop::init( ) {
service_chair = new int[barber]; // indicate the current customer thread id
in_service = new bool[barber];
money_paid = new bool[barber];
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond_customers_waiting, NULL);
cond_customer_served = new pthread_cond_t[barber];
cond_barber_paid = new pthread_cond_t[barber];
cond_barber_sleeping = new pthread_cond_t[barber];
for (int i = 0; i < barber; i++) {
service_chair[i] = 0;
in_service[i] = false;
money_paid[i] = false;
pthread_cond_init(&cond_customer_served[i], NULL);
pthread_cond_init(&cond_barber_paid[i], NULL);
pthread_cond_init(&cond_barber_sleeping[i], NULL);
}
}
Shop::~Shop(){
delete [] service_chair;
service_chair = NULL;
delete [] in_service;
in_service = NULL;
delete [] money_paid;
money_paid = NULL;
delete [] cond_customer_served;
cond_customer_served = NULL;
delete [] cond_barber_paid;
cond_barber_paid = NULL;
delete [] cond_barber_sleeping;
cond_barber_sleeping = NULL;
}
string Shop::int2string( int i ) {
stringstream out;
out << i;
return out.str( );
}
void Shop::print( int person, string message ) {
cout << ( ( person > 0 ) ? "customer[" : "barber [" )
<< abs(person) << "]: " << message << endl;
}
int Shop::visitShop( int customerID ) {
pthread_mutex_lock( &mutex ); // lock
if ( waiting_chairs.size( ) == max ) { // waiting chairs are all occupied
print( customerID,"leaves the shop because of no available waiting chairs.");
++nDropsOff;
pthread_mutex_unlock( &mutex );
return -1; // leave the shop
}
if ( hasServiceChair() == -1 || !waiting_chairs.empty( ) ) {
// someone is being served or transitting from a waiting to a service chair
waiting_chairs.push( customerID ); // have a waiting chair
print( customerID, "takes a waiting chair. # waiting seats available = "
+ int2string( max - waiting_chairs.size( ) ) );
pthread_cond_wait( &cond_customers_waiting, &mutex );
waiting_chairs.pop( ); // stand up
}
print( customerID, "moves to the service chair. # waiting seats available = "
+ int2string( max - waiting_chairs.size( ) ) );
int availableServiceChair = hasServiceChair();
if ( service_chair[availableServiceChair] == 0) {
service_chair[availableServiceChair] = customerID; // have the service chair
in_service[availableServiceChair] = true;
}
// wake up the barber just in case if he is sleeping based on service chair
pthread_cond_signal( &cond_barber_sleeping[availableServiceChair] );
pthread_mutex_unlock( &mutex ); // unlock
return availableServiceChair;
}
void Shop::leaveShop(int customerId, int barberId ) {
pthread_mutex_lock( &mutex ); // lock
print( customerId,"wait for barber[" + int2string( barberId ) + "] to be done with haircut" );
while ( in_service[barberId] == true ) // while being served
pthread_cond_wait( &cond_customer_served[barberId], &mutex ); // just sit.
money_paid[barberId] = true;
pthread_cond_signal( &cond_barber_paid[barberId] );
print( customerId, "says good-bye to the barber." );
pthread_mutex_unlock( &mutex ); // unlock
}
void Shop::helloCustomer(int barberId ) {
pthread_mutex_lock( &mutex ); // lock
if ( waiting_chairs.empty( ) && service_chair[barberId] == 0 ) { // no customers
print( -barberId, "sleeps because of no customers." );
pthread_cond_wait( &cond_barber_sleeping[barberId], &mutex ); // then, let's sleep
}
if ( service_chair[barberId] == 0 ) { // check if the customer, sit down.
pthread_cond_wait(&cond_barber_sleeping[barberId], &mutex);
}
print( -barberId,"starts a hair-cut service for customer[" + int2string( service_chair[barberId] ) + "]" );
pthread_mutex_unlock( &mutex ); // unlock
}
void Shop::byeCustomer(int barberId ) {
pthread_mutex_lock( &mutex ); // lock
in_service[barberId] = false;
print( -barberId, "says he's done with a hair-cut service for " +
int2string( service_chair[barberId] ) );
money_paid[barberId] = false;
pthread_cond_signal( &cond_customer_served[barberId] ); // tell the customer "done"
while ( money_paid[barberId] == false )
pthread_cond_wait( &cond_barber_paid[barberId], &mutex );
service_chair[barberId] = 0;
print( -barberId, "calls in another customer" );
pthread_cond_signal( &cond_customers_waiting ); // call in another one
pthread_mutex_unlock( &mutex ); // unlock
}
int Shop::hasServiceChair(){
for(int i=0; i< barber; i++){
if(service_chair[i]==0){
return i;
}
}
return -1;
}