Cleaned code
This commit is contained in:
parent
5bf764f537
commit
24c0d9e89b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
assignment2.exe
|
assignment2.exe
|
||||||
|
assignment2
|
||||||
|
BIN
assignment2
BIN
assignment2
Binary file not shown.
@ -13,17 +13,17 @@
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
#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 NFLOORS 20 // The number of floors in the building
|
||||||
#define NPEOPLE 3 // The number of people in the building
|
#define NPEOPLE 20 // The number of people in the building
|
||||||
#define MAXNOINLIFT 10 // Maximum number of people in a lift
|
#define MAXNOINLIFT 10 // Maximum number of people in a lift
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Define delay times (in milliseconds)
|
// Define delay times (in milliseconds)
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
//#define SUPERSLOW
|
//#define SUPERSLOW
|
||||||
//#define SLOW
|
//#define SLOW
|
||||||
//#define FAST
|
//#define FAST
|
||||||
#define SUPERFAST
|
#define SUPERFAST
|
||||||
|
|
||||||
#if defined(SUPERSLOW)
|
#if defined(SUPERSLOW)
|
||||||
#define LIFTSPEED 500 // The time it takes for the lift to move one floor
|
#define LIFTSPEED 500 // The time it takes for the lift to move one floor
|
||||||
#define GETINSPEED 250 // The time it takes to get into the lift
|
#define GETINSPEED 250 // The time it takes to get into the lift
|
||||||
@ -52,54 +52,63 @@
|
|||||||
#define UP 1
|
#define UP 1
|
||||||
#define DOWN -1
|
#define DOWN -1
|
||||||
|
|
||||||
|
// Define the lower-case true so that this compiles directly in Windows (GCC 9.2)
|
||||||
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
|
#define true 1
|
||||||
|
#endif
|
||||||
|
// Print the number of people in the lifts & on the floors
|
||||||
|
//#define POPULATIONS
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Information about a floor in the building
|
// Information about a floor in the building
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
int waitingtogoup; // The number of people waiting to go up
|
int waitingtogoup; // The number of people waiting to go up
|
||||||
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
|
semaphore queueInteraction; // People can't all press a button at the same time
|
||||||
// Add a tracker to include how many people are currently moving into/out of a lift.
|
|
||||||
// These people are still considered to be waiting, but a thread is in the process of loading them
|
|
||||||
int inprogress_up;
|
|
||||||
int inprogress_down;
|
|
||||||
} floor_info;
|
} floor_info;
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Information about a lift
|
// Information about a lift
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
int no; // The lift number (id)
|
int no; // The lift number (id)
|
||||||
int position; // The floor it is on
|
int position; // The floor it is on
|
||||||
int direction; // Which direction it is going (UP/DOWN)
|
int direction; // Which direction it is going (UP/DOWN)
|
||||||
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 stating if a thread is currently loading/unloading someone from the lift
|
|
||||||
//semaphore loading;
|
|
||||||
// If the target floor is being selected (only one can press at a time)
|
|
||||||
//semaphore buttonPress;
|
|
||||||
} lift_info;
|
} lift_info;
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Some global variables
|
// Some global variables
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
floor_info floors[NFLOORS];
|
floor_info floors[NFLOORS];
|
||||||
lift_info* targetLift[NFLOORS];
|
lift_info *targetLift[NFLOORS]; // 2-dimensional array of the lift
|
||||||
|
semaphore targetLiftSelect[NFLOORS];
|
||||||
|
|
||||||
// Bound all printing to this semaphore
|
// Bound all printing to this semaphore
|
||||||
semaphore printSemaphore;
|
semaphore printSemaphore;
|
||||||
|
// If printing people counts, int array and semaphore to keep track of them
|
||||||
|
#ifdef POPULATIONS
|
||||||
|
semaphore updateFloorCount;
|
||||||
|
int floorCount[NFLOORS];
|
||||||
|
// count of times since value was zero, used to help find a stuck person
|
||||||
|
int floorCountZeroInc[NFLOORS];
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// 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_fast(int x, int y, const char *s)
|
||||||
|
{
|
||||||
// Lock our print to just one thread (stops x,y from changing)
|
// Lock our print to just one thread (stops x,y from changing)
|
||||||
semaphore_wait(&printSemaphore);
|
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(0);
|
Sleep(0);
|
||||||
@ -108,7 +117,31 @@ void print_at_xy(int x, int y, const char *s) {
|
|||||||
printf("%s", s);
|
printf("%s", s);
|
||||||
|
|
||||||
// Move cursor out of the way
|
// Move cursor out of the way
|
||||||
gotoxy(42, NFLOORS+2);
|
gotoxy(42, NFLOORS + 2);
|
||||||
|
// flush the stream and release the semaphore
|
||||||
|
fflush(stdout);
|
||||||
|
semaphore_signal(&printSemaphore);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Print a string on the screen at position (x,y)
|
||||||
|
// --------------------------------------------------
|
||||||
|
void print_at_xy(int x, int y, const char *s)
|
||||||
|
{
|
||||||
|
// Lock our print to just one thread (stops x,y from changing)
|
||||||
|
semaphore_wait(&printSemaphore);
|
||||||
|
// Move cursor to (x,y)
|
||||||
|
gotoxy(x, y);
|
||||||
|
|
||||||
|
// Slow things down
|
||||||
|
Sleep(1);
|
||||||
|
|
||||||
|
// Print the string
|
||||||
|
printf("%s", s);
|
||||||
|
|
||||||
|
// Move cursor out of the way
|
||||||
|
gotoxy(42, NFLOORS + 2);
|
||||||
// flush the stream and release the semaphore
|
// flush the stream and release the semaphore
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
semaphore_signal(&printSemaphore);
|
semaphore_signal(&printSemaphore);
|
||||||
@ -118,35 +151,38 @@ void print_at_xy(int x, int y, const char *s) {
|
|||||||
// Function for a lift to pick people waiting on a
|
// Function for a lift to pick people waiting on a
|
||||||
// floor going in a certain direction
|
// floor going in a certain direction
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void get_into_lift(lift_info *lift, int direction) {
|
void get_into_lift(lift_info *lift, int direction)
|
||||||
|
{
|
||||||
// Local variables
|
// Local variables
|
||||||
int *waiting;
|
int *waiting;
|
||||||
int *inprogress;
|
|
||||||
semaphore *s;
|
semaphore *s;
|
||||||
|
|
||||||
// Check lift direction
|
// Check lift direction
|
||||||
if(direction==UP) {
|
if (direction == UP)
|
||||||
|
{
|
||||||
// Use up_arrow semaphore
|
// Use up_arrow semaphore
|
||||||
s = &floors[lift->position].up_arrow;
|
s = &floors[lift->position].up_arrow;
|
||||||
|
|
||||||
// Number of people waiting to go up
|
// Number of people waiting to go up
|
||||||
waiting = &floors[lift->position].waitingtogoup;
|
waiting = &floors[lift->position].waitingtogoup;
|
||||||
inprogress = &floors[lift->position].inprogress_up;
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
// Use down_arrow semaphore
|
// Use down_arrow semaphore
|
||||||
s = &floors[lift->position].down_arrow;
|
s = &floors[lift->position].down_arrow;
|
||||||
|
|
||||||
// Number of people waiting to go down
|
// Number of people waiting to go down
|
||||||
waiting = &floors[lift->position].waitingtogodown;
|
waiting = &floors[lift->position].waitingtogodown;
|
||||||
inprogress = &floors[lift->position].inprogress_down;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Problems here are primarily state consistency. Between the start of the conditional, the number of waiting people can change, resulting
|
// Problems here are primarily state consistency. Between the start of the conditional, the number of waiting people can change, resulting
|
||||||
// in the number of waiting people dropping below zero.
|
// in the number of waiting people dropping below zero.
|
||||||
// For all the people waiting
|
// For all the people waiting
|
||||||
while(*waiting) {
|
while (*waiting)
|
||||||
|
{
|
||||||
// Check if lift is empty
|
// Check if lift is empty
|
||||||
if(lift->peopleinlift == 0) {
|
if (lift->peopleinlift == 0)
|
||||||
|
{
|
||||||
// Set the direction of the lift
|
// Set the direction of the lift
|
||||||
lift->direction = direction;
|
lift->direction = direction;
|
||||||
}
|
}
|
||||||
@ -154,32 +190,25 @@ void get_into_lift(lift_info *lift, int direction) {
|
|||||||
// Check there are people waiting and lift isn't full. Ignore in-progress (moving into lift) people
|
// Check there are people waiting and lift isn't full. Ignore in-progress (moving into lift) people
|
||||||
// must check here
|
// must check here
|
||||||
semaphore_wait(&floors[lift->position].queueInteraction);
|
semaphore_wait(&floors[lift->position].queueInteraction);
|
||||||
if(lift->peopleinlift < MAXNOINLIFT && *waiting - *inprogress) {
|
if (lift->peopleinlift < MAXNOINLIFT && *waiting)
|
||||||
//volatile int pos = floors[lift->position].waitingtogodown + floors[lift->position].waitingtogoup - (*inprogress);
|
{
|
||||||
(*inprogress)++;
|
|
||||||
//semaphore_signal(&floors[lift->position].queueInteraction);
|
|
||||||
// Add person to the lift
|
// Add person to the lift
|
||||||
lift->peopleinlift++;
|
lift->peopleinlift++;
|
||||||
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, " ");
|
||||||
// Capture the person's printed position while we have the
|
|
||||||
//semaphore_signal(&floors[lift->position].queueInteraction);
|
|
||||||
// Do the print, no need to hold the semaphore while this is going on
|
|
||||||
|
|
||||||
// One less person waiting
|
|
||||||
// Note that while loading, the queue cannot change
|
|
||||||
//semaphore_wait(&floors[lift->position].queueInteraction);
|
|
||||||
|
|
||||||
(*waiting)--;
|
(*waiting)--;
|
||||||
(*inprogress)--;
|
|
||||||
semaphore_signal(&floors[lift->position].queueInteraction);
|
semaphore_signal(&floors[lift->position].queueInteraction);
|
||||||
|
|
||||||
|
|
||||||
// Wait for person to get into lift
|
// Wait for person to get into lift
|
||||||
Sleep(GETINSPEED);
|
Sleep(GETINSPEED);
|
||||||
// Need a sem here
|
// Need a sem here
|
||||||
|
// Wait til we can be the lift that is loading
|
||||||
|
semaphore_wait(&targetLiftSelect[lift->position]);
|
||||||
targetLift[lift->position] = lift;
|
targetLift[lift->position] = lift;
|
||||||
semaphore_signal(s);
|
semaphore_signal(s);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
semaphore_signal(&floors[lift->position].queueInteraction);
|
semaphore_signal(&floors[lift->position].queueInteraction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -189,7 +218,8 @@ void get_into_lift(lift_info *lift, int direction) {
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Function for the Lift Threads
|
// Function for the Lift Threads
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void* lift_thread(void *p) {
|
void *lift_thread(void *p)
|
||||||
|
{
|
||||||
// Local variables
|
// Local variables
|
||||||
lift_info lift;
|
lift_info lift;
|
||||||
int no = (long long)p;
|
int no = (long long)p;
|
||||||
@ -204,8 +234,9 @@ void* lift_thread(void *p) {
|
|||||||
//semaphore_create(&lift.loading, 1);
|
//semaphore_create(&lift.loading, 1);
|
||||||
//semaphore_create(&lift.buttonPress, 1);
|
//semaphore_create(&lift.buttonPress, 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,56 +247,66 @@ void* lift_thread(void *p) {
|
|||||||
Sleep(rnd(1000));
|
Sleep(rnd(1000));
|
||||||
|
|
||||||
// Loop forever
|
// Loop forever
|
||||||
while(true) {
|
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);
|
||||||
// Wait for a while
|
// Wait for a while
|
||||||
Sleep(LIFTSPEED);
|
Sleep(LIFTSPEED);
|
||||||
|
|
||||||
|
// Print the number of people in the lift
|
||||||
|
#ifdef POPULATIONS
|
||||||
|
char str[12];
|
||||||
|
sprintf(str, "%d", lift.peopleinlift);
|
||||||
|
print_at_xy_fast(no * 4 + 1, NFLOORS + 5, " ");
|
||||||
|
print_at_xy_fast(no * 4 + 1, NFLOORS + 5, str);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 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.loading);
|
|
||||||
lift.peopleinlift--;
|
lift.peopleinlift--;
|
||||||
//semaphore_signal(&lift.loading);
|
|
||||||
// One less waiting to get off at this floor
|
// One less waiting to get off at this floor
|
||||||
// Don't need a semaphore as nothing should read this value now
|
|
||||||
//semaphore_wait(&lift.buttonPress);
|
|
||||||
lift.stops[lift.position]--;
|
lift.stops[lift.position]--;
|
||||||
//semaphore_signal(&lift.buttonPress);
|
|
||||||
|
|
||||||
// Wait for exit lift delay
|
// Wait for exit lift delay
|
||||||
Sleep(GETOUTSPEED);
|
Sleep(GETOUTSPEED);
|
||||||
|
|
||||||
semaphore_signal(&lift.stopsem[lift.position]);
|
|
||||||
// Signal passenger to leave lift
|
// Signal passenger to leave lift
|
||||||
|
semaphore_signal(&lift.stopsem[lift.position]);
|
||||||
|
|
||||||
|
|
||||||
// Check if that was the last passenger waiting for this floor
|
// Check if that was the last passenger waiting for this floor
|
||||||
if(!lift.stops[lift.position]) {
|
if (!lift.stops[lift.position])
|
||||||
|
{
|
||||||
// Clear the "-"
|
// Clear the "-"
|
||||||
print_at_xy(no*4+1+2, NFLOORS-lift.position, " ");
|
print_at_xy(no * 4 + 1 + 2, NFLOORS - lift.position, " ");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if lift is going up or is empty
|
// Check if lift is going up or is empty
|
||||||
if(lift.direction==UP || !lift.peopleinlift) {
|
if (lift.direction == UP || !lift.peopleinlift)
|
||||||
|
{
|
||||||
// Pick up passengers waiting to go up
|
// Pick up passengers waiting to go up
|
||||||
get_into_lift(&lift, UP);
|
get_into_lift(&lift, UP);
|
||||||
}
|
}
|
||||||
// Check if lift is going down or is empty
|
// Check if lift is going down or is empty
|
||||||
if(lift.direction==DOWN || !lift.peopleinlift) {
|
if (lift.direction == DOWN || !lift.peopleinlift)
|
||||||
|
{
|
||||||
// Pick up passengers waiting to go down
|
// Pick up passengers waiting to go down
|
||||||
get_into_lift(&lift, DOWN);
|
get_into_lift(&lift, DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase lift from screen
|
// Erase lift from screen
|
||||||
print_at_xy(no*4+1, NFLOORS-lift.position, (lift.direction + 1 ? " " : lc));
|
print_at_xy(no * 4 + 1, NFLOORS - lift.position, (lift.direction + 1 ? " " : lc));
|
||||||
|
|
||||||
// Move lift
|
// Move lift
|
||||||
lift.position += lift.direction;
|
lift.position += lift.direction;
|
||||||
|
|
||||||
// Check if lift is at top or bottom
|
// Check if lift is at top or bottom
|
||||||
if(lift.position == 0 || lift.position == NFLOORS-1) {
|
if (lift.position == 0 || lift.position == NFLOORS - 1)
|
||||||
|
{
|
||||||
// Change lift direction
|
// Change lift direction
|
||||||
lift.direction = -lift.direction;
|
lift.direction = -lift.direction;
|
||||||
}
|
}
|
||||||
@ -277,43 +318,44 @@ void* lift_thread(void *p) {
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Function for the Person Threads
|
// Function for the Person Threads
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void* person_thread(void *p) {
|
void *person_thread(void *p)
|
||||||
|
{
|
||||||
// Local variables
|
// Local variables
|
||||||
int from = 0, to; // Start on the ground floor
|
int from = 0, to; // Start on the ground floor
|
||||||
lift_info *lift;
|
lift_info *lift;
|
||||||
|
|
||||||
// Randomise
|
// Randomise
|
||||||
randomise();
|
randomise();
|
||||||
|
|
||||||
// Stay in the building forever
|
// Stay in the building forever
|
||||||
while(true) {
|
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;
|
semaphore *s;
|
||||||
// Wait for our turn to press a button
|
|
||||||
|
|
||||||
// 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
|
||||||
semaphore_wait(&floors[from].queueInteraction);
|
semaphore_wait(&floors[from].queueInteraction);
|
||||||
floors[from].waitingtogoup++;
|
floors[from].waitingtogoup++;
|
||||||
//volatile int pos = floors[from].waitingtogoup +floors[from].waitingtogodown - floors[from].inprogress_down - floors[from].inprogress_up;
|
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);
|
|
||||||
semaphore_signal(&floors[from].queueInteraction);
|
semaphore_signal(&floors[from].queueInteraction);
|
||||||
// Print person waiting
|
// Print person waiting
|
||||||
|
|
||||||
s = &floors[from].up_arrow;
|
s = &floors[from].up_arrow;
|
||||||
// Wait for a lift to arrive (going up)
|
// Wait for a lift to arrive (going up)
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
semaphore_wait(&floors[from].queueInteraction);
|
semaphore_wait(&floors[from].queueInteraction);
|
||||||
// One more person waiting to go down
|
// One more person waiting to go down
|
||||||
floors[from].waitingtogodown++;
|
floors[from].waitingtogodown++;
|
||||||
//volatile int pos = floors[from].waitingtogoup +floors[from].waitingtogodown - floors[from].inprogress_down - floors[from].inprogress_up;
|
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);
|
|
||||||
semaphore_signal(&floors[from].queueInteraction);
|
semaphore_signal(&floors[from].queueInteraction);
|
||||||
// Print person waiting
|
// Print person waiting
|
||||||
// We want this to happen after the semaphore is released, so the person is added after any deletions
|
// We want this to happen after the semaphore is released, so the person is added after any deletions
|
||||||
@ -327,21 +369,33 @@ void* person_thread(void *p) {
|
|||||||
|
|
||||||
// Which lift we are getting into
|
// Which lift we are getting into
|
||||||
lift = targetLift[from];
|
lift = targetLift[from];
|
||||||
|
// Realease the target-lift semaphore
|
||||||
|
semaphore_signal(&targetLiftSelect[lift->position]);
|
||||||
// Add one to passengers waiting for floor
|
// Add one to passengers waiting for floor
|
||||||
// Only one person enters at a time
|
|
||||||
//semaphore_wait(&lift->buttonPress);
|
|
||||||
lift->stops[to]++;
|
lift->stops[to]++;
|
||||||
//semaphore_signal(&lift->buttonPress);
|
|
||||||
// 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, "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore_wait(&lift->stopsem[to]);
|
semaphore_wait(&lift->stopsem[to]);
|
||||||
// Wait until we are at the right floor
|
// Wait until we are at the right floor
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POPULATIONS
|
||||||
|
semaphore_wait(&updateFloorCount);
|
||||||
|
floorCount[to]++;
|
||||||
|
floorCount[from]--;
|
||||||
|
semaphore_signal(&updateFloorCount);
|
||||||
|
// Print the current person's floor
|
||||||
|
char str[3];
|
||||||
|
sprintf(str, "%d", to);
|
||||||
|
print_at_xy_fast((long long)p * 4 + 1, NFLOORS + 8, " ");
|
||||||
|
print_at_xy_fast((long long)p * 4 + 1, NFLOORS + 8, str);
|
||||||
|
#endif
|
||||||
// Exit the lift
|
// Exit the lift
|
||||||
from = to;
|
from = to;
|
||||||
}
|
}
|
||||||
@ -352,26 +406,31 @@ 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
|
// Print the whole building before anything else
|
||||||
// Print Roof
|
// Print Roof
|
||||||
printf("%s", tl);
|
printf("%s", tl);
|
||||||
for(l = 0; l < NLIFTS-1; l++) {
|
for (l = 0; l < NLIFTS - 1; l++)
|
||||||
|
{
|
||||||
printf("%s%s%s%s", hl, td, hl, td);
|
printf("%s%s%s%s", hl, td, hl, td);
|
||||||
}
|
}
|
||||||
printf("%s%s%s%s\n", hl, td, hl, tr);
|
printf("%s%s%s%s\n", hl, td, hl, tr);
|
||||||
|
|
||||||
// Print Floors and Lifts
|
// Print Floors and Lifts
|
||||||
for(f = NFLOORS-1; f >= 0; f--) {
|
for (f = NFLOORS - 1; f >= 0; f--)
|
||||||
for(l = 0; l < NLIFTS; l++) {
|
{
|
||||||
|
for (l = 0; l < NLIFTS; l++)
|
||||||
|
{
|
||||||
printf("%s%s%s ", vl, lc, vl);
|
printf("%s%s%s ", vl, lc, vl);
|
||||||
if(l == NLIFTS-1) {
|
if (l == NLIFTS - 1)
|
||||||
|
{
|
||||||
printf("%s\n", vl);
|
printf("%s\n", vl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,75 +438,133 @@ void printbuilding(void) {
|
|||||||
|
|
||||||
// Print Ground
|
// Print Ground
|
||||||
printf("%s", bl);
|
printf("%s", bl);
|
||||||
for(l = 0; l < NLIFTS-1; l++) {
|
for (l = 0; l < NLIFTS - 1; l++)
|
||||||
|
{
|
||||||
printf("%s%s%s%s", hl, tu, hl, tu);
|
printf("%s%s%s%s", hl, tu, hl, tu);
|
||||||
}
|
}
|
||||||
printf("%s%s%s%s\n", hl, tu, hl, br);
|
printf("%s%s%s%s\n", hl, tu, hl, br);
|
||||||
|
|
||||||
// Print Message
|
// Print Message
|
||||||
printf("Lift Simulation - Press CTRL-Break to exit\n");
|
printf("Lift Simulation - Press CTRL-Break to exit\n");
|
||||||
|
|
||||||
|
#ifdef POPULATIONS
|
||||||
|
gotoxy(0, NFLOORS + 7);
|
||||||
|
printf("People\'s Destination Floors:");
|
||||||
|
gotoxy(0, NFLOORS + 4);
|
||||||
|
printf("Lift Occupants:");
|
||||||
|
gotoxy(4 * NLIFTS + NPEOPLE + 5, 0);
|
||||||
|
printf("Number of People on Floor:");
|
||||||
|
#endif
|
||||||
// Ensure buffer is written
|
// Ensure buffer is written
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
// Once the building has been printed, then we can those waiting to print that they may do so
|
// Once the building has been printed, then we can those waiting to print that they may do so
|
||||||
semaphore_signal(&printSemaphore);
|
semaphore_signal(&printSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef POPULATIONS
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Iterate through the floors and update the queue size
|
// Iterate through the floors and update the queue size
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void* update_floor_counts(void *p){
|
void *update_floor_counts(void *p)
|
||||||
while(true){
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < NFLOORS; i++){
|
int k;
|
||||||
char str[12];
|
char str2[17] = {';',' ', 'i', 't', 'e', 'r', 's', ' ', 's', 'i', 'n', 'c', 'e', ' ', '0', ':', ' '};
|
||||||
sprintf(str, "%d", floors[i].waitingtogodown + floors[i].waitingtogoup);
|
while (true)
|
||||||
print_at_xy(4*NLIFTS+NPEOPLE, NFLOORS-i, " ");
|
{
|
||||||
print_at_xy(4*NLIFTS+NPEOPLE, NFLOORS-i, str);
|
for (i = -1; i < NFLOORS; i++)
|
||||||
|
{
|
||||||
|
char str[48];
|
||||||
|
char str3[12];
|
||||||
|
if (i != -1)
|
||||||
|
{
|
||||||
|
if (floorCount[i] != 0){
|
||||||
|
floorCountZeroInc[i]++;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
floorCountZeroInc[i] = 0;
|
||||||
|
}
|
||||||
|
sprintf(str, "%d", floorCount[i]);
|
||||||
|
sprintf(str3, "%d", floorCountZeroInc[i]);
|
||||||
|
strcat(str, str2);
|
||||||
|
strcat(str, str3);
|
||||||
|
print_at_xy_fast(4 * NLIFTS + NPEOPLE + 5, NFLOORS - i, " ");
|
||||||
|
print_at_xy_fast(4 * NLIFTS + NPEOPLE + 5, NFLOORS - i, str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ttl = 0;
|
||||||
|
for (k = 0; k < NFLOORS; k++)
|
||||||
|
{
|
||||||
|
ttl += floorCount[k];
|
||||||
|
}
|
||||||
|
sprintf(str, "%d", ttl);
|
||||||
|
if (ttl != NPEOPLE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
print_at_xy_fast(4 * NLIFTS + NPEOPLE + 5, NFLOORS - i, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Sleep(0);
|
Sleep(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
// Main starts the threads and then waits.
|
// Main starts the threads and then waits.
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
// Local variables
|
// Local variables
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
semaphore_create(&printSemaphore, 0);
|
semaphore_create(&printSemaphore, 0);
|
||||||
// Initialise Building
|
// Initialise Building
|
||||||
for(i = 0; i < NFLOORS; i++) {
|
for (i = 0; i < NFLOORS; i++)
|
||||||
// Initialise Floor
|
{
|
||||||
floors[i].inprogress_down = 0;
|
|
||||||
floors[i].inprogress_up = 0;
|
|
||||||
floors[i].waitingtogoup = 0;
|
floors[i].waitingtogoup = 0;
|
||||||
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
|
semaphore_create(&floors[i].queueInteraction, 1); // This initially has one available button press
|
||||||
|
semaphore_create(&targetLiftSelect[i], 1); // This initially has one available button press
|
||||||
|
#ifdef POPULATIONS
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
semaphore_create(&updateFloorCount, 1); // Moved, to save excessive preprocessor tags
|
||||||
|
floorCount[0] = NPEOPLE;
|
||||||
|
floorCountZeroInc[0] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
floorCount[i] = 0;
|
||||||
|
floorCountZeroInc[i] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Initialise any other semaphores ---
|
// --- Initialise any other semaphores ---
|
||||||
|
|
||||||
// Print Building
|
// Print Building
|
||||||
printbuilding();
|
printbuilding();
|
||||||
|
|
||||||
// Create Lifts
|
// Create Lifts
|
||||||
for(i = 0; i < NLIFTS; i++) {
|
for (i = 0; i < NLIFTS; i++)
|
||||||
|
{
|
||||||
// Create Lift Thread
|
// Create Lift Thread
|
||||||
create_thread(lift_thread, (void*)i);
|
create_thread(lift_thread, (void *)i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create People
|
// Create People
|
||||||
for(i = 0; i < NPEOPLE; i++) {
|
for (i = 0; i < NPEOPLE; i++)
|
||||||
|
{
|
||||||
// Create Person Thread
|
// Create Person Thread
|
||||||
create_thread(person_thread, (void*)i);
|
create_thread(person_thread, (void *)i);
|
||||||
}
|
}
|
||||||
//create_thread(update_floor_counts, (void*)i);
|
#ifdef POPULATIONS
|
||||||
|
create_thread(update_floor_counts, (void *)i);
|
||||||
|
#endif
|
||||||
// Go to sleep for 86400 seconds (one day)
|
// Go to sleep for 86400 seconds (one day)
|
||||||
Sleep(86400000ULL);
|
Sleep(86400000ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user