Got the sample working
This commit is contained in:
parent
23e4d99071
commit
ed6cc593b6
@ -49,6 +49,7 @@ typedef struct {
|
|||||||
int waitingtogodown; // The number of people waiting to go down
|
int waitingtogodown; // The number of people waiting to go down
|
||||||
semaphore up_arrow; // People going up wait on this
|
semaphore up_arrow; // People going up wait on this
|
||||||
semaphore down_arrow; // People going down wait on this
|
semaphore down_arrow; // People going down wait on this
|
||||||
|
semaphore queueInteraction; // People can't all press a button at the same time
|
||||||
} floor_info;
|
} floor_info;
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
@ -61,20 +62,27 @@ typedef struct {
|
|||||||
int peopleinlift; // The number of people in the lift
|
int peopleinlift; // The number of people in the lift
|
||||||
int stops[NFLOORS]; // How many people are going to each floor
|
int stops[NFLOORS]; // How many people are going to each floor
|
||||||
semaphore stopsem[NFLOORS]; // People in the lift wait on one of these
|
semaphore stopsem[NFLOORS]; // People in the lift wait on one of these
|
||||||
|
semaphore load;
|
||||||
} lift_info;
|
} lift_info;
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Some global variables
|
// Some global variables
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
floor_info floors[NFLOORS];
|
floor_info floors[NFLOORS];
|
||||||
|
lift_info* targetLift[NFLOORS];
|
||||||
|
|
||||||
|
// Bound all printing to this semaphore
|
||||||
|
semaphore printSemaphore;
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Print a string on the screen at position (x,y)
|
// Print a string on the screen at position (x,y)
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void print_at_xy(int x, int y, const char *s) {
|
void print_at_xy(int x, int y, const char *s) {
|
||||||
|
semaphore_wait(&printSemaphore);
|
||||||
// Move cursor to (x,y)
|
// Move cursor to (x,y)
|
||||||
gotoxy(x,y);
|
gotoxy(x,y);
|
||||||
|
|
||||||
|
|
||||||
// Slow things down
|
// Slow things down
|
||||||
Sleep(1);
|
Sleep(1);
|
||||||
|
|
||||||
@ -83,6 +91,8 @@ void print_at_xy(int x, int y, const char *s) {
|
|||||||
|
|
||||||
// Move cursor out of the way
|
// Move cursor out of the way
|
||||||
gotoxy(42, NFLOORS+2);
|
gotoxy(42, NFLOORS+2);
|
||||||
|
fflush(stdout);
|
||||||
|
semaphore_signal(&printSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
@ -120,7 +130,9 @@ void get_into_lift(lift_info *lift, int direction) {
|
|||||||
// Check there are people waiting and lift isn't full
|
// Check there are people waiting and lift isn't full
|
||||||
if(lift->peopleinlift < MAXNOINLIFT && *waiting) {
|
if(lift->peopleinlift < MAXNOINLIFT && *waiting) {
|
||||||
// Add person to the lift
|
// Add person to the lift
|
||||||
|
semaphore_wait(&lift->load);
|
||||||
lift->peopleinlift++;
|
lift->peopleinlift++;
|
||||||
|
semaphore_signal(&lift->load);
|
||||||
|
|
||||||
// Erase the person from the waiting queue
|
// Erase the person from the waiting queue
|
||||||
print_at_xy(NLIFTS*4+floors[lift->position].waitingtogodown + floors[lift->position].waitingtogoup, NFLOORS-lift->position, " ");
|
print_at_xy(NLIFTS*4+floors[lift->position].waitingtogodown + floors[lift->position].waitingtogoup, NFLOORS-lift->position, " ");
|
||||||
@ -130,12 +142,8 @@ void get_into_lift(lift_info *lift, int direction) {
|
|||||||
|
|
||||||
// Wait for person to get into lift
|
// Wait for person to get into lift
|
||||||
Sleep(GETINSPEED);
|
Sleep(GETINSPEED);
|
||||||
//semaphore_wait(s);
|
targetLift[lift->position] = lift;
|
||||||
semaphore_wait(lift->stopsem);
|
semaphore_signal(s);
|
||||||
semaphore_signal(lift->stopsem);
|
|
||||||
//--//semaphore_signal(s);
|
|
||||||
// Set lift to enter
|
|
||||||
// Signal passenger to enter
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -157,6 +165,8 @@ void* lift_thread(void *p) {
|
|||||||
lift.direction = UP; // Lift starts going up
|
lift.direction = UP; // Lift starts going up
|
||||||
lift.peopleinlift = 0; // Lift starts empty
|
lift.peopleinlift = 0; // Lift starts empty
|
||||||
|
|
||||||
|
semaphore_create(&lift.load, 1);
|
||||||
|
|
||||||
for(i = 0; i < NFLOORS; i++) {
|
for(i = 0; i < NFLOORS; i++) {
|
||||||
lift.stops[i]=0; // No passengers waiting
|
lift.stops[i]=0; // No passengers waiting
|
||||||
semaphore_create(&lift.stopsem[i], 0); // Initialise semaphores
|
semaphore_create(&lift.stopsem[i], 0); // Initialise semaphores
|
||||||
@ -169,7 +179,7 @@ void* lift_thread(void *p) {
|
|||||||
Sleep(rnd(1000));
|
Sleep(rnd(1000));
|
||||||
|
|
||||||
// Loop forever
|
// Loop forever
|
||||||
while(1 == 1) {
|
while(TRUE) {
|
||||||
// Print current position of the lift
|
// Print current position of the lift
|
||||||
print_at_xy(no*4+1, NFLOORS-lift.position, lf);
|
print_at_xy(no*4+1, NFLOORS-lift.position, lf);
|
||||||
|
|
||||||
@ -179,14 +189,16 @@ void* lift_thread(void *p) {
|
|||||||
// Drop off passengers on this floor
|
// Drop off passengers on this floor
|
||||||
while (lift.stops[lift.position] != 0) {
|
while (lift.stops[lift.position] != 0) {
|
||||||
// One less passenger in lift
|
// One less passenger in lift
|
||||||
|
semaphore_wait(&lift.load);
|
||||||
lift.peopleinlift--;
|
lift.peopleinlift--;
|
||||||
|
|
||||||
// One less waiting to get off at this floor
|
// One less waiting to get off at this floor
|
||||||
lift.stops[lift.position]--;
|
lift.stops[lift.position]--;
|
||||||
|
semaphore_signal(&lift.load);
|
||||||
// Wait for exit lift delay
|
// Wait for exit lift delay
|
||||||
Sleep(GETOUTSPEED);
|
Sleep(GETOUTSPEED);
|
||||||
semaphore_signal(&lift.stopsem[i]);
|
|
||||||
|
semaphore_signal(&lift.stopsem[lift.position]);
|
||||||
// Signal passenger to leave lift
|
// Signal passenger to leave lift
|
||||||
|
|
||||||
// Check if that was the last passenger waiting for this floor
|
// Check if that was the last passenger waiting for this floor
|
||||||
@ -234,50 +246,54 @@ void* person_thread(void *p) {
|
|||||||
randomise();
|
randomise();
|
||||||
|
|
||||||
// Stay in the building forever
|
// Stay in the building forever
|
||||||
while(1) {
|
while(TRUE) {
|
||||||
// Work for a while
|
// Work for a while
|
||||||
Sleep(rnd(PEOPLESPEED));
|
Sleep(rnd(PEOPLESPEED));
|
||||||
do {
|
do {
|
||||||
// Randomly pick another floor to go to
|
// Randomly pick another floor to go to
|
||||||
to = rnd(NFLOORS);
|
to = rnd(NFLOORS);
|
||||||
} while(to == from);
|
} while(to == from);
|
||||||
|
semaphore* s;
|
||||||
|
// Wait for our turn to press a button
|
||||||
|
semaphore_wait(&floors[from].queueInteraction);
|
||||||
// Check which direction the person is going (UP/DOWN)
|
// Check which direction the person is going (UP/DOWN)
|
||||||
if(to > from) {
|
if(to > from) {
|
||||||
// One more person waiting to go up
|
// One more person waiting to go up
|
||||||
floors[from].waitingtogoup++;
|
floors[from].waitingtogoup++;
|
||||||
|
semaphore_signal(&floors[from].queueInteraction);
|
||||||
// Print person waiting
|
// Print person waiting
|
||||||
print_at_xy(NLIFTS*4+ floors[from].waitingtogoup +floors[from].waitingtogodown,NFLOORS-from, pr);
|
print_at_xy(NLIFTS*4+ floors[from].waitingtogoup +floors[from].waitingtogodown,NFLOORS-from, pr);
|
||||||
while (1){
|
s = &floors[from].up_arrow;
|
||||||
if (lift->direction == 0){
|
// Wait for a lift to arrive (going up)
|
||||||
lift
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--- // Wait for a lift to arrive (going up)
|
|
||||||
} else {
|
} else {
|
||||||
// One more person waiting to go down
|
// One more person waiting to go down
|
||||||
floors[from].waitingtogodown++;
|
floors[from].waitingtogodown++;
|
||||||
|
semaphore_signal(&floors[from].queueInteraction);
|
||||||
// Print person waiting
|
// Print person waiting
|
||||||
print_at_xy(NLIFTS*4+floors[from].waitingtogodown+floors[from].waitingtogoup,NFLOORS-from, pr);
|
print_at_xy(NLIFTS*4+floors[from].waitingtogodown+floors[from].waitingtogoup,NFLOORS-from, pr);
|
||||||
|
s = &floors[from].down_arrow;
|
||||||
--- // Wait for a lift to arrive (going down)
|
// Wait for a lift to arrive (going down)
|
||||||
}
|
}
|
||||||
|
// We've pressed our button
|
||||||
|
|
||||||
|
semaphore_wait(s);
|
||||||
|
|
||||||
// Which lift we are getting into
|
// Which lift we are getting into
|
||||||
--- lift = ;
|
lift = targetLift[from];
|
||||||
|
|
||||||
// Add one to passengers waiting for floor
|
// Add one to passengers waiting for floor
|
||||||
|
// Only one person enters at a time
|
||||||
|
semaphore_wait(&lift->load);
|
||||||
lift->stops[to]++;
|
lift->stops[to]++;
|
||||||
|
semaphore_signal(&lift->load);
|
||||||
// Press button if we are the first
|
// Press button if we are the first
|
||||||
if(lift->stops[to]==1) {
|
if(lift->stops[to]==1) {
|
||||||
// Print light for destination
|
// Print light for destination
|
||||||
print_at_xy(lift->no*4+1+2, NFLOORS-to, "-");
|
print_at_xy(lift->no*4+1+2, NFLOORS-to, "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
--- // Wait until we are at the right floor
|
semaphore_wait(&lift->stopsem[to]);
|
||||||
|
// Wait until we are at the right floor
|
||||||
|
|
||||||
// Exit the lift
|
// Exit the lift
|
||||||
from = to;
|
from = to;
|
||||||
@ -290,12 +306,14 @@ void* person_thread(void *p) {
|
|||||||
// Print the building on the screen
|
// Print the building on the screen
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void printbuilding(void) {
|
void printbuilding(void) {
|
||||||
|
|
||||||
// Local variables
|
// Local variables
|
||||||
int l,f;
|
int l,f;
|
||||||
|
|
||||||
// Clear Screen
|
// Clear Screen
|
||||||
system(clear_screen);
|
system(clear_screen);
|
||||||
|
// Print the whole building before anything else
|
||||||
|
semaphore_wait(&printSemaphore);
|
||||||
// Print Roof
|
// Print Roof
|
||||||
printf("%s", tl);
|
printf("%s", tl);
|
||||||
for(l = 0; l < NLIFTS-1; l++) {
|
for(l = 0; l < NLIFTS-1; l++) {
|
||||||
@ -322,6 +340,9 @@ void printbuilding(void) {
|
|||||||
|
|
||||||
// Print Message
|
// Print Message
|
||||||
printf("Lift Simulation - Press CTRL-Break to exit\n");
|
printf("Lift Simulation - Press CTRL-Break to exit\n");
|
||||||
|
// Ensure buffer is written
|
||||||
|
fflush(stdout);
|
||||||
|
semaphore_signal(&printSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
@ -330,7 +351,7 @@ void printbuilding(void) {
|
|||||||
int main() {
|
int main() {
|
||||||
// Local variables
|
// Local variables
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
semaphore_create(&printSemaphore, 1);
|
||||||
// Initialise Building
|
// Initialise Building
|
||||||
for(i = 0; i < NFLOORS; i++) {
|
for(i = 0; i < NFLOORS; i++) {
|
||||||
// Initialise Floor
|
// Initialise Floor
|
||||||
@ -338,6 +359,7 @@ int main() {
|
|||||||
floors[i].waitingtogodown = 0;
|
floors[i].waitingtogodown = 0;
|
||||||
semaphore_create(&floors[i].up_arrow, 0);
|
semaphore_create(&floors[i].up_arrow, 0);
|
||||||
semaphore_create(&floors[i].down_arrow, 0);
|
semaphore_create(&floors[i].down_arrow, 0);
|
||||||
|
semaphore_create(&floors[i].queueInteraction, 1); // This initially has one available button press
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Initialise any other semaphores ---
|
// --- Initialise any other semaphores ---
|
||||||
|
20
logic.md
Normal file
20
logic.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Logic
|
||||||
|
## Initial State:
|
||||||
|
* Lifts all at the bottom of the building
|
||||||
|
* People all outside the building
|
||||||
|
* not waiting on an arrow
|
||||||
|
* not in a lift
|
||||||
|
|
||||||
|
## State 1:
|
||||||
|
### *These are performed simulataneously*
|
||||||
|
---
|
||||||
|
* Lift Thread
|
||||||
|
1. Lift waits for a short amount of time (to allow people to enter the building)
|
||||||
|
2. If no one is in the lift, it calls `get_into_lift()`
|
||||||
|
3. `get_into_lift()` checks if someone is waiting on the up arrow semaphore
|
||||||
|
4. Two things must then happen:
|
||||||
|
* First, the lift must update the lift that currently is on that floor
|
||||||
|
* Second, the lift must signal to a passenger that it may enter.
|
||||||
|
---
|
||||||
|
* Person Thread
|
||||||
|
1.
|
Loading…
x
Reference in New Issue
Block a user