From ed6cc593b6906fd6b99ec7ee3512f00f0e7ccff8 Mon Sep 17 00:00:00 2001 From: Brychan Dempsey Date: Tue, 27 Apr 2021 17:08:11 +1200 Subject: [PATCH] Got the sample working --- assignment2_handout.c | 78 +++++++++++++++++++++++++++---------------- logic.md | 20 +++++++++++ 2 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 logic.md diff --git a/assignment2_handout.c b/assignment2_handout.c index f1ff5e1..3ffd2b5 100644 --- a/assignment2_handout.c +++ b/assignment2_handout.c @@ -11,7 +11,7 @@ // -------------------------------------------------- // Define Problem Size // -------------------------------------------------- -#define NLIFTS 4 // The number of lifts in the building +#define NLIFTS 4 // The number of lifts in the building #define NFLOORS 20 // The number of floors in the building #define NPEOPLE 20 // The number of people in the building #define MAXNOINLIFT 10 // Maximum number of people in a lift @@ -49,6 +49,7 @@ typedef struct { int waitingtogodown; // The number of people waiting to go down semaphore up_arrow; // People going up 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; // -------------------------------------------------- @@ -61,20 +62,27 @@ typedef struct { int peopleinlift; // The number of people in the lift int stops[NFLOORS]; // How many people are going to each floor semaphore stopsem[NFLOORS]; // People in the lift wait on one of these + semaphore load; } lift_info; // -------------------------------------------------- // Some global variables // -------------------------------------------------- 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) // -------------------------------------------------- void print_at_xy(int x, int y, const char *s) { + semaphore_wait(&printSemaphore); // Move cursor to (x,y) gotoxy(x,y); + // Slow things down Sleep(1); @@ -83,6 +91,8 @@ void print_at_xy(int x, int y, const char *s) { // Move cursor out of the way 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 if(lift->peopleinlift < MAXNOINLIFT && *waiting) { // Add person to the lift + semaphore_wait(&lift->load); lift->peopleinlift++; + semaphore_signal(&lift->load); // Erase the person from the waiting queue 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 Sleep(GETINSPEED); - //semaphore_wait(s); - semaphore_wait(lift->stopsem); - semaphore_signal(lift->stopsem); - //--//semaphore_signal(s); - // Set lift to enter - // Signal passenger to enter + targetLift[lift->position] = lift; + semaphore_signal(s); } else { break; } @@ -157,6 +165,8 @@ void* lift_thread(void *p) { lift.direction = UP; // Lift starts going up lift.peopleinlift = 0; // Lift starts empty + semaphore_create(&lift.load, 1); + for(i = 0; i < NFLOORS; i++) { lift.stops[i]=0; // No passengers waiting semaphore_create(&lift.stopsem[i], 0); // Initialise semaphores @@ -169,7 +179,7 @@ void* lift_thread(void *p) { Sleep(rnd(1000)); // Loop forever - while(1 == 1) { + while(TRUE) { // Print current position of the lift 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 while (lift.stops[lift.position] != 0) { // One less passenger in lift + semaphore_wait(&lift.load); lift.peopleinlift--; // One less waiting to get off at this floor lift.stops[lift.position]--; - + semaphore_signal(&lift.load); // Wait for exit lift delay Sleep(GETOUTSPEED); - semaphore_signal(&lift.stopsem[i]); + + semaphore_signal(&lift.stopsem[lift.position]); // Signal passenger to leave lift // Check if that was the last passenger waiting for this floor @@ -234,50 +246,54 @@ void* person_thread(void *p) { randomise(); // Stay in the building forever - while(1) { + while(TRUE) { // Work for a while Sleep(rnd(PEOPLESPEED)); do { // Randomly pick another floor to go to to = rnd(NFLOORS); } 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) if(to > from) { // One more person waiting to go up floors[from].waitingtogoup++; - + semaphore_signal(&floors[from].queueInteraction); // Print person waiting print_at_xy(NLIFTS*4+ floors[from].waitingtogoup +floors[from].waitingtogodown,NFLOORS-from, pr); - while (1){ - if (lift->direction == 0){ - lift - } - } ---- // Wait for a lift to arrive (going up) + s = &floors[from].up_arrow; + // Wait for a lift to arrive (going up) } else { // One more person waiting to go down floors[from].waitingtogodown++; - + semaphore_signal(&floors[from].queueInteraction); // Print person waiting print_at_xy(NLIFTS*4+floors[from].waitingtogodown+floors[from].waitingtogoup,NFLOORS-from, pr); - ---- // Wait for a lift to arrive (going down) + s = &floors[from].down_arrow; + // Wait for a lift to arrive (going down) } + // We've pressed our button + + semaphore_wait(s); // Which lift we are getting into ---- lift = ; + lift = targetLift[from]; // Add one to passengers waiting for floor + // Only one person enters at a time + semaphore_wait(&lift->load); lift->stops[to]++; - + semaphore_signal(&lift->load); // Press button if we are the first if(lift->stops[to]==1) { // Print light for destination 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 from = to; @@ -290,19 +306,21 @@ void* person_thread(void *p) { // Print the building on the screen // -------------------------------------------------- void printbuilding(void) { + // Local variables int l,f; // Clear Screen system(clear_screen); - + // Print the whole building before anything else + semaphore_wait(&printSemaphore); // Print Roof printf("%s", tl); for(l = 0; l < NLIFTS-1; l++) { printf("%s%s%s%s", hl, td, hl, td); } printf("%s%s%s%s\n", hl, td, hl, tr); - + // Print Floors and Lifts for(f = NFLOORS-1; f >= 0; f--) { for(l = 0; l < NLIFTS; l++) { @@ -322,6 +340,9 @@ void printbuilding(void) { // Print Message 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() { // Local variables unsigned long i; - + semaphore_create(&printSemaphore, 1); // Initialise Building for(i = 0; i < NFLOORS; i++) { // Initialise Floor @@ -338,6 +359,7 @@ int main() { floors[i].waitingtogodown = 0; semaphore_create(&floors[i].up_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 --- diff --git a/logic.md b/logic.md new file mode 100644 index 0000000..9c90a87 --- /dev/null +++ b/logic.md @@ -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. \ No newline at end of file