-
Notifications
You must be signed in to change notification settings - Fork 0
/
advanced elevator problem.c
159 lines (147 loc) · 5.49 KB
/
advanced elevator problem.c
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
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int currentTime=0;
typedef struct {
int id; /* 0, 1, 2, 3, … */
int from_floor, to_floor; /* i.e., from where to where */
double arrival_time; /* The time at which the person arrives */
int pickedUp;
int droppedOff;
/* You can add more fields if you want */
} person;
typedef struct {
int id; /* 0, 1, 2, 3, … */
int current_floor; /* Current location of the elevator */
pthread_mutex_t lock;
//pthread_cond_v cv; /* Will be used to block the elevator if there is no request */
person *people;/* All the people currently inside the elevator */
/* You can add more fields if you want */
int currentCount;
int index;
} elevator;
typedef struct { /* All the global information related to the elevator simulation */
int num_elevators;
int num_floors;
int beginning_time;
int elevator_speed;
int simulation_time;
int random_seed;
int num_people_started; /* statistics */
int num_people_finished; /* statistics */
pthread_mutex_t *lock;
} gv;
int count=0;
int totalPeopleGenerated = 0;
int totalPeopleCompleted = 0;
gv obj1;
person *waiting_people; //people waiting for elevator
void* generatePeople(void *arg){
waiting_people = malloc(1000*sizeof(person)); //Assuming Size of doubly linked list to be 1000
int index = 0;
while(1){ //keep on generating people
sleep(obj1.beginning_time);
currentTime+=obj1.beginning_time;
person p;
p.id = index;
p.arrival_time = index;
p.from_floor = rand() % obj1.num_floors + 1;
p.to_floor = rand() % obj1.num_floors + 1;
p.pickedUp = 0;
p.droppedOff = 0;
while(p.from_floor==p.to_floor)
p.to_floor = rand() % obj1.num_floors + 1;
waiting_people[index] = p; //person waiting for elevator
printf("[%d]Person id = %d arrives on floor = %d, waiting to go to floor = %d\n",currentTime,p.id,p.from_floor,p.to_floor);
count++;
index++;
totalPeopleGenerated++;
}
}
int pickUpIndex = 0;
void* moveElevator(void *arg){
elevator e;
e.current_floor=0; //Assuming each elevator starts from ground floor
e.id=(int)arg;
e.people = malloc(1000*sizeof(person)); //Assuming Size of doubly linked list to be 1000
e.index = 0;
while(1){
while(count==0){
sleep(1);
}
person p = waiting_people[pickUpIndex++]; //increment pickup index so that other thread works on another person
p.pickedUp=1;
count--;
if(e.current_floor != p.from_floor)
printf("[%d]Elevator %d moving from %d to %d\n",currentTime,e.id,e.current_floor,p.from_floor);
if(e.current_floor<p.from_floor){ // elevator needs to go up
while(e.current_floor < p.from_floor){
sleep(obj1.elevator_speed);
e.current_floor++;
int i;
printf("[%d]Elevator %d arrives at floor %d\n",currentTime,e.id,e.current_floor);
for(i=0;i<totalPeopleGenerated;i++){
if(waiting_people[i].pickedUp == 0 && waiting_people[i].from_floor==e.current_floor && waiting_people[i].to_floor <=p.from_floor) { //last condition ensures it only picks someone who wanna go up
e.people[e.index++] = waiting_people[i];
waiting_people[i].pickedUp = 1;
e.currentCount++; //increment number of people currently on elevator
printf("[%d]Elevator %d picks up person %d\n",currentTime,e.id,waiting_people[i].id);
}
}
for(i=0;i<e.currentCount;i++){
if(e.people[i].droppedOff==0 && e.people[i].to_floor == e.current_floor) {
totalPeopleCompleted++;
e.people[i].droppedOff = 1;
printf("[%d]Elevator %d drops person %d\n",currentTime,e.id,e.people[i].id);
}
}
}
} else{ //elevator needs to go down
while(e.current_floor > p.from_floor){
sleep(obj1.elevator_speed);
e.current_floor--;
int i;
printf("[%d]Elevator %d arrives at floor %d\n",currentTime,e.id,e.current_floor);
for(i=0;i<totalPeopleGenerated;i++){
if(waiting_people[i].pickedUp == 0 && waiting_people[i].from_floor==e.current_floor && waiting_people[i].to_floor >=p.from_floor) { //last condition ensures it only picks someone who wanna go down
e.people[e.index++] = waiting_people[i];
waiting_people[i].pickedUp = 1;
e.currentCount++; //increment number of people currently on elevator
printf("[%d]Elevator %d picks up person %d\n",currentTime,e.id,waiting_people[i].id);
}
}
for(i=0;i<e.currentCount;i++){
if(e.people[i].droppedOff==0 && e.people[i].to_floor == e.current_floor) {
totalPeopleCompleted++;
e.people[i].droppedOff = 1;
printf("[%d]Elevator %d drops person %d\n",currentTime,e.id,e.people[i].id);
}
}
}
}
printf("[%d]Elevator %d picks up person %d\n",currentTime,e.id,p.id); //eventually elevator reaches person's floor
}
}
int main(int argc, char *argv[]){
obj1.num_elevators = atoi(argv[1]);
obj1.num_floors = atoi(argv[2]);
obj1.beginning_time = atoi(argv[3]);
obj1.elevator_speed = atoi(argv[4]);
obj1.simulation_time = atoi(argv[5]);
obj1.random_seed = atoi(argv[6]);
pthread_t pgt,et[obj1.num_elevators];
pthread_create(&pgt, NULL, generatePeople, NULL);
int i;
for(i=0;i<obj1.num_elevators;i++){
pthread_create(&et[i],NULL,moveElevator,(void*) i);
}
sleep(obj1.simulation_time);
pthread_cancel(pgt);
for(i=0;i<obj1.num_elevators;i++){
pthread_cancel(et[i]);
}
printf("Simulation Result: %d people started, %d people finished during %d seconds\n",totalPeopleGenerated,totalPeopleCompleted,obj1.simulation_time);
pthread_exit(NULL);
}