-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathelevator.cpp
More file actions
218 lines (187 loc) · 5.26 KB
/
Copy pathelevator.cpp
File metadata and controls
218 lines (187 loc) · 5.26 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include "elevator.h"
// Constructor for elevator object class.
// Both elevator processes should construct one with a different name such that it'll be independently controlled.
elevator::elevator(string name){
// Mutex
theMutex = new CMutex(string("__Mutex") + name);
// Datapool
datapool = new CDataPool(string("__Data") + name, sizeof(struct thedata));
datapool_ptr = (struct thedata*)(datapool->LinkDataPool()); // get pointer to data pool
// syncrhoinzation semaphores for producer / consumer
ps1 = new CSemaphore(string("PS1") + name, 0, 2); // semaphore with initial value 0 and max value 1
ps2 = new CSemaphore(string("PS2") + name, 0, 2); // semaphore with initial value 0 and max value 1
cs1 = new CSemaphore(string("CS1") + name, 1, 2); // semaphore with initial value 1 and max value 1
cs2 = new CSemaphore(string("CS2") + name, 1, 2); // semaphore with initial value 1 and max value 1
}
// Destructor and deletes all dynamically allocated variables
elevator::~elevator(){
delete theMutex;
delete datapool;
delete ps1;
delete ps2;
delete cs1;
delete cs2;
}
// Termination function; to be called after elevators are terminated.
void elevator::ITS_TIME_TO_END(){
// We only signal producers because they are the ones waiting for new writes. We want to end with a read.
ps1->Signal();
ps2->Signal();
}
// Producer consumer semaphore functions
// Waits for both io and dispatcher to finish reading, then locks data, then writes to it
// Then signals to them the OK to read
// Does not write until it knows dispatcher and io has read the last instance of write.
void elevator::Update_Status(thedata update) {
CSemaphore completion("done", 0, 2);
cs1->Wait();
if (completion.Read() > 1)
return;
cs2->Wait();
if (completion.Read() > 1)
return;
// Data lock
theMutex->Wait();
*datapool_ptr = update;
theMutex->Signal();
ps1->Signal();
ps2->Signal();
}
// Copies/reads data to dispatcher and signals that it has been copied/read.
// Does not copy/read until it has been updated.
void elevator::GetElevatorStatus_dispatcher(thedata &update) {
CSemaphore completion("done", 0, 2);
ps2->Wait();
if (completion.Read() > 1)
return;
// Data lock
theMutex->Wait();
update = *datapool_ptr;
theMutex->Signal();
cs2->Signal();
}
// Copies/reads data to IO and signals that it has been copied/read.
// Does not copy/read until it has been updated.
void elevator::GetElevatorStatus_io(thedata &update) {
CSemaphore completion("done", 0, 2);
ps1->Wait();
if (completion.Read() > 1)
return;
// Data lock
theMutex->Wait();
update = *datapool_ptr;
theMutex->Signal();
cs1->Signal();
}
passenger::passenger(int passnumin) {
passnum = passnumin;
srand((unsigned)time(0));
// Get random number from 0-9 for request floor
request_floor = (UINT)(rand() % 10);
// Get random number from 0-9 for dest floor
dest_floor = (UINT)(rand() % 10);
// Must make them not to be equal
if (dest_floor == request_floor){
if (dest_floor == 9)
dest_floor--;
else
dest_floor++;
}
// Get direction from passenger's request floor - passengers dest floor
dir = (request_floor < dest_floor) ? UP : DOWN;
for (int i = 0; i < 10; ++i) {
EV1UP[i] = new CCondition(to_string(i) + "ev1up");
EV1DW[i] = new CCondition(to_string(i) + "ev1dw");
EV2UP[i] = new CCondition(to_string(i) + "ev2up");
EV2DW[i] = new CCondition(to_string(i) + "ev2dw");
}
}
// Delete everything
passenger:: ~passenger() {
}
int passenger::main() {
// First make a [U/D][0-9] command
CTypedPipe <io_dispatcher_pipeline> pipe2("input", 1024);
console.Wait();
MOVE_CURSOR(0, 20+passnum);
cout << "P" << passnum << "R: " << request_floor;
console.Signal();
if (dir == UP)
temp.first = 'u';
else
temp.first = 'd';
temp.second = '0' + request_floor;
only_one.Wait();
pipe2.Write(&temp);
only_one.Signal();
// Wait for elevator to arrive signal using ccondition
temp.first = 'x';
while (temp.first == 'x'){
Sleep(200);
if (dir == UP){
if (EV2UP[(int)request_floor]->Test()) {
temp.first = '2';
}
else if (EV1UP[(int)request_floor]->Test()) { //Works
temp.first = '1';
}
else
temp.first = 'x';
}
else{
if (EV2DW[(int)request_floor]->Test())
temp.first = '2';
else if (EV1DW[(int)request_floor]->Test())
temp.first = '1';
else
temp.first = 'x';
}
}
// Reset the ones that wasn't used if both directions were signalled
if (EV1UP[(int)request_floor]->Test()){}
if (EV1DW[(int)request_floor]->Test()){}
if (EV2DW[(int)request_floor]->Test()){}
if (EV2UP[(int)request_floor]->Test()){}
// Second make a [1/2][0-9] command
temp.second = '0' + dest_floor;
only_one.Wait();
pipe2.Write(&temp);
only_one.Signal();
console.Wait();
MOVE_CURSOR(8, 20+passnum);
cout << "D: " << dest_floor << " E" << temp.first;
console.Signal();
if (temp.first == '1') {
if (dir == UP) {
while (!EV1UP[(int)dest_floor]->Test()) {
Sleep(200);
}
}
else {
while (!EV1DW[(int)dest_floor]->Test()) {
Sleep(200);
}
}
}
else {
if (dir == UP){
while(!EV2UP[(int)dest_floor]->Test()){
Sleep(200);
}
}
else{
while(!EV2DW[(int)dest_floor]->Test()){
Sleep(200);
}
}
}
for (int i = 0; i < 10; ++i){
delete EV1UP[i];
delete EV2UP[i];
delete EV1DW[i];
delete EV2DW[i];
}
// Suicide
delete this;
return 0;
}