diff --git a/Building/Building.c b/Building/Building.c index 9e75a78..47d7636 100644 --- a/Building/Building.c +++ b/Building/Building.c @@ -2,6 +2,7 @@ // Created by Antoine Bartuccio on 05/06/2018. // #include +#include #include "Building.h" #include "../Resident/Resident.h" #include "../Visitor/Visitor.h" @@ -16,9 +17,28 @@ void remove_end_char(char * string, char character){ string[string_size - 1] = '\0'; } -int get_target_Building(THIS(Building)){ +/** + * Get the best call for the elevator + *@param THIS(Building) : this + *@param elevator_floor : actual floor of the requesting elevator + *@returns the closest floor where a client is calling as an int. If no client is calling, returns -1. + */ +int get_next_call_Building(THIS(Building), int elevator_floor){ + pthread_mutex_lock(this->mutex_func_get_next_call); int* waiting_floors = this->get_waiting_floors(this); - return waiting_floors[1]; + int i; + float best_diff = INFINITY; + int next_target = -1; + for(i=0; i 0){ + if(abs(elevator_floor - waiting_floors[i]) < best_diff){ + best_diff = abs(elevator_floor - waiting_floors[i]); + next_target = waiting_floors[i]; + } + } + } + pthread_mutex_unlock(this->mutex_func_get_next_call); + return next_target; } List * split(char * line, char * separator){ @@ -125,6 +145,9 @@ void _free__Building(THIS(Building)){ pthread_mutex_unlock(this->mutex_func_get_inside_elevator); pthread_mutex_destroy(this->mutex_func_get_inside_elevator); + pthread_mutex_unlock(this->mutex_func_get_next_call); + pthread_mutex_destroy(this->mutex_func_get_next_call); + pthread_mutex_unlock(&this->mutex_waiting_floors); pthread_mutex_destroy(&this->mutex_waiting_floors); @@ -140,7 +163,7 @@ void _free__Building(THIS(Building)){ free(this->mutex_cond_get_inside_elevator); free(this->mutex_cond_get_outside_elevator); free(this->mutex_func_get_inside_elevator); - //free(&this->mutex_waiting_floors); + free(this->mutex_func_get_next_call); free(this->elevators); free(this); @@ -237,10 +260,12 @@ Building *_init_Building(char * residents_file, char * visitors_file){ new_building->mutex_cond_get_inside_elevator = malloc_or_die(sizeof(pthread_mutex_t)); new_building->mutex_cond_get_outside_elevator = malloc_or_die(sizeof(pthread_mutex_t)); new_building->mutex_func_get_inside_elevator = malloc_or_die(sizeof(pthread_mutex_t)); + new_building->mutex_func_get_next_call = malloc_or_die(sizeof(pthread_mutex_t)); pthread_mutex_init(new_building->mutex_cond_get_inside_elevator, NULL); pthread_mutex_init(new_building->mutex_cond_get_outside_elevator, NULL); pthread_mutex_init(new_building->mutex_func_get_inside_elevator, NULL); + pthread_mutex_init(new_building->mutex_func_get_next_call, NULL); new_building->condition_floors = malloc_or_die(sizeof(pthread_cond_t*) * FLOORS); new_building->residents = NEW(List); @@ -262,7 +287,7 @@ Building *_init_Building(char * residents_file, char * visitors_file){ get_inside_elevator, use_call_box, go_to_floor, - get_target, + get_next_call, get_waiting_floors, signal_elevator_at_floor ) diff --git a/Building/Building.h b/Building/Building.h index 3879d8c..d642d7d 100644 --- a/Building/Building.h +++ b/Building/Building.h @@ -25,6 +25,7 @@ typedef struct o_Building { PRIVATE pthread_mutex_t * mutex_cond_get_inside_elevator; PRIVATE pthread_mutex_t * mutex_cond_get_outside_elevator; PRIVATE pthread_mutex_t * mutex_func_get_inside_elevator; + PRIVATE pthread_mutex_t * mutex_func_get_next_call; PRIVATE pthread_cond_t ** condition_floors; PRIVATE void (*parse_residents)(_THIS(Building), char * file); @@ -33,7 +34,7 @@ typedef struct o_Building { PUBLIC int (*use_call_box)(_THIS(Building), char * resident_name); PUBLIC void (*signal_elevator_at_floor)(_THIS(Building), int floor); - PUBLIC int (*get_target)(_THIS(Building)); + PUBLIC int (*get_next_call)(_THIS(Building), int elevator_floor); PUBLIC int* (*get_waiting_floors)(_THIS(Building)); SYNCHRONIZE PUBLIC void (*go_to_floor)(_THIS(Building), int origin, int destination, Passenger * passenger); @@ -44,7 +45,6 @@ typedef struct o_Building { FRIENDLY(residents, SharedData) FRIENDLY(visitors, SharedData) FRIENDLY(elevators, SharedData) -FRIENDLY(waiting_passengers, SharedData) Building *_init_Building(char * residents_file, char * visitors_file); diff --git a/Elevator/Elevator.c b/Elevator/Elevator.c index af010f8..6f679dc 100644 --- a/Elevator/Elevator.c +++ b/Elevator/Elevator.c @@ -51,10 +51,10 @@ int get_number_of_passengers_Elevator(THIS(Elevator)){ /** * Search the closest floor where the elevator should stop. In practice ( for now ), it means that this function returns the closest floor amongs it's passengers destinations. * @THIS(Elevator) a pointer the current Elevator - * @return the found floor as an int. If no passengers are in the elevator, returns 0 ( as the elevator should come back to floor 0 ). + * @return the found floor as an int. If no passengers are in the elevator, returns -1. * @todo should consider passenger calling the elevator */ -int get_next_floor_Elevator(THIS(Elevator)){ +int get_next_passenger_stop_Elevator(THIS(Elevator)){ int i, next_floor, temp_floor; float min_diff; Element* temp_element; @@ -63,7 +63,7 @@ int get_next_floor_Elevator(THIS(Elevator)){ pthread_mutex_lock(&this->mutex_floor); min_diff = INFINITY; - next_floor = 0; + next_floor = -1; for(i=0;ipassengers->get_size(this->passengers);i++){ temp_element = this->passengers->get_element(this->passengers, i); @@ -105,14 +105,22 @@ void *runnable_Elevator(void * void_this){ /* This is where the thread logic will be implemented */ Elevator * this = (Elevator*) void_this; SharedData * data = GET_INSTANCE(SharedData); + Building * building = data->main_building; AGENT_OPTIONS printf("Je suis l'ascenseur %s\n", this->name); for (;;){ - data->main_building->get_waiting_floors(data->main_building); - data->main_building->signal_elevator_at_floor(data->main_building, this->get_floor(this)); - this->set_floor(this, this->get_next_floor(this)); + building->signal_elevator_at_floor(data->main_building, this->get_floor(this)); + if(this->target_floor == this->get_floor(this)){ + if(this->get_next_passenger_stop(this) != -1){ + this->target_floor = this->get_next_passenger_stop(this); + }else if(building->get_next_call(building, this->floor) != -1){ + this->target_floor = building->get_next_call(building, this->floor); + } + + } + this->set_floor(this, this->target_floor); } return NULL; @@ -122,21 +130,22 @@ Elevator *_init_Elevator(char * name){ Elevator * new_elevator = malloc_or_die(sizeof(Elevator)); new_elevator->name = strdup(name); new_elevator->passengers = NEW(List); + new_elevator->target_floor = 0; pthread_mutex_init(&new_elevator->mutex_passengers, NULL); pthread_mutex_init(&new_elevator->mutex_state, NULL); pthread_mutex_init(&new_elevator->mutex_floor, NULL); LINK_ALL(Elevator, new_elevator, - runnable, - get_number_of_passengers, - get_next_floor, - can_get_inside, - add_passenger, - get_state, - set_state, - get_floor, - set_floor, - repair + runnable, + get_number_of_passengers, + get_next_passenger_stop, + can_get_inside, + add_passenger, + get_state, + set_state, + get_floor, + set_floor, + repair ); new_elevator->set_floor(new_elevator, 0); diff --git a/Elevator/Elevator.h b/Elevator/Elevator.h index d953315..766b6e1 100644 --- a/Elevator/Elevator.h +++ b/Elevator/Elevator.h @@ -20,6 +20,7 @@ typedef struct o_Elevator { PRIVATE List * passengers; PRIVATE char * name; PRIVATE int floor; + PRIVATE int target_floor; PRIVATE pthread_mutex_t mutex_passengers; PRIVATE pthread_mutex_t mutex_state; PRIVATE pthread_mutex_t mutex_floor; @@ -28,7 +29,7 @@ typedef struct o_Elevator { SYNCHRONIZE PRIVATE void (*set_state)(_THIS(Elevator), ELEVATOR_STATE var); SYNCHRONIZE PRIVATE void (*set_floor)(_THIS(Elevator), int var); - SYNCHRONIZE PRIVATE int (*get_next_floor)(_THIS(Elevator)); + SYNCHRONIZE PRIVATE int (*get_next_passenger_stop)(_THIS(Elevator)); SYNCHRONIZE PUBLIC void (*repair)(_THIS(Elevator)); SYNCHRONIZE PUBLIC int (*get_number_of_passengers)(_THIS(Elevator));