/* There shall be one task, called lift_task, for the lift. */ void lift_task(void)//TODO { int next; int dirchange; int send_task_id; int length;//DUMMY message_data_type msg; draw_lift(mainlift); while (1) { si_message_receive((char *) &msg, &length, &send_task_id); if(msg.type == MOVE_MESSAGE) { lift_next_floor(mainlift, &next, &dirchange); lift_move(mainlift, next, dirchange); lift_has_arrived(mainlift); } else if(msg.type == TRAVEL_MESSAGE) { /* a travel message is sent to the lift task when a person would like to make a lift travel */ enter_floor(mainlift, msg.id, msg.from_floor, msg.to_floor); } draw_lift(mainlift); } }
/* MONITOR function lift_travel: performs a journey with the lift starting at from_floor, and ending at to_floor */ void lift_travel(lift_type lift, int id, int from_floor, int to_floor) { pthread_mutex_lock(&lift->mutex); enter_floor(lift, id, from_floor); // vänta på att lift has arrived cv while(1) { pthread_cond_wait(&lift->change, &lift->mutex); if(lift->floor == from_floor) { // försök att gå in i liften if (enter_lift(lift, id, from_floor, to_floor)) { draw_lift(lift); pthread_cond_broadcast(&lift->change); break; } } } // vänta på att liften har nått rätt våning while(1) { pthread_cond_wait(&lift->change, &lift->mutex); if(lift->floor == to_floor) { if (leave_lift(lift, id, to_floor)) { draw_lift(lift); pthread_cond_broadcast(&lift->change); break; } } } pthread_mutex_unlock(&lift->mutex); }
/* The shall be one task for each person. All person tasks shall be implemented by the same C function, called passenger_task. */ void passenger_task(void) { //printf("blaba\n"); int id; int length; int send_task_id; int current; int from; int to; /* receive id */ si_message_receive((char *) &id, &length, &send_task_id); current = random_level(); while (1) { from = current; to = random_level(); si_sem_wait(&mainlift->mutex); enter_floor(mainlift,id, current);//spawna si_sem_signal(&mainlift->mutex); printf("Passenger %d starting journey from %d to %d.\n", id, from, to); lift_travel(mainlift, id, from, to);//res current = to; printf("Passenger %d arrived at %d.\n", id, current); si_sem_wait(&mainlift->mutex); leave_floor(mainlift, id, current);//ta bort från våning si_sem_signal(&mainlift->mutex); si_wait_n_ms(TIME_TO_NEW_JOURNEY); } }
/* MONITOR function lift_travel: performs a journey with the lift starting at from_floor, and ending at to_floor */ void lift_travel(lift_type lift, int id, int from_floor, int to_floor) { pthread_mutex_lock(&lift->mutex); enter_floor(lift, id, from_floor); while(passenger_wait_for_lift(lift, from_floor)){ pthread_cond_wait(&lift->change, &lift->mutex); } leave_floor(lift, id, from_floor); enter_lift(lift, id, to_floor); pthread_cond_broadcast(&lift->change); while(!passenger_should_leave_lift(lift, to_floor)){ pthread_cond_wait(&lift->change, &lift->mutex); } exit_lift(lift, id); pthread_cond_broadcast(&lift->change); pthread_mutex_unlock(&lift->mutex); }
static void lift_process(void) { lift_type Lift; Lift = lift_create(); int change_direction, next_floor, tmp_id, tmp_to_floor; struct long_time_msg done_m; done_m.type = LIFT_TRAVEL_DONE; char msgbuf[4096]; int found = 0; int from_floor_list[MAX_N_PERSONS][MAX_TRIP_LEN]; // Contains the from_floors for trips int to_floor_list[MAX_N_PERSONS][MAX_TRIP_LEN]; // Contains the to_floors for trips int iterations[MAX_N_PERSONS]; // Which iteration is the persons on int trip_len[MAX_N_PERSONS]; // Trip length for the persons struct timeval starttime[MAX_N_PERSONS][MAX_TRIP_LEN]; // Keeps track of timing of each persons trips long long int timediff[MAX_N_PERSONS][MAX_TRIP_LEN]; struct timeval tmp_time; while(1) { int i; int j; int id_array[MAX_N_PERSONS * N_FLOORS]; //struct lift_msg reply; struct lift_msg *m; struct long_lift_msg *long_m; int count, tmp_id; message_send((char *) Lift, sizeof(*Lift), QUEUE_UI, 0); // Draw the lift int len = message_receive(msgbuf, 4096, QUEUE_LIFT); // Wait for a message if(len < sizeof(struct lift_msg)) { fprintf(stderr, "Message too short\n"); continue; } if (len == sizeof(struct lift_msg)) { m = (struct lift_msg *) msgbuf; // We now that this is a LIFT_MOVE msg /* Check if someone wants to leave at this floor */ for (i = 0; i < MAX_N_PASSENGERS; i++) { if (Lift->passengers_in_lift[i].id != NO_ID && Lift->passengers_in_lift[i].to_floor == Lift->floor) { tmp_id = Lift->passengers_in_lift[i].id; leave_lift(Lift, tmp_id, Lift->passengers_in_lift[i].to_floor); // Calculate elapsed time gettimeofday(&tmp_time, NULL); timediff[tmp_id][iterations[tmp_id]] = (tmp_time.tv_sec*1000000ULL + tmp_time.tv_usec) - (starttime[tmp_id][iterations[tmp_id]].tv_sec*1000000ULL + starttime[tmp_id][iterations[tmp_id]].tv_usec); // printf("Person %d finished an iteration in %lld \n", tmp_id, timediff[tmp_id][iterations[tmp_id]]); //printf("Person %d leave lift.\n", tmp_id); if (iterations[tmp_id] < trip_len[tmp_id] - 1) { iterations[tmp_id]++; // Start timing for that person gettimeofday(&starttime[tmp_id][iterations[tmp_id]], NULL); enter_floor(Lift, tmp_id, from_floor_list[tmp_id][iterations[tmp_id]], to_floor_list[tmp_id][iterations[tmp_id]]); // printf("Person %d enter floor %d.\n", tmp_id, //from_floor_list[tmp_id][iterations[tmp_id]]); } else { // Send done message with elapsed time info // printf("Sending done message to person %d.\n", tmp_id); //printf("Sent timediff: "); done_m.person_id = tmp_id; // fill message with info, person knows how many iterations he made for (i=0; i < trip_len[tmp_id]; i++) { done_m.timediff[i] = timediff[tmp_id][i]; // printf("%lld, ", done_m.timediff[i]); } // printf("\n"); message_send((char *) &done_m, sizeof(done_m), QUEUE_FIRSTPERSON + tmp_id, 0); // printf("Message sent to person %d\n", tmp_id); } } } /* Check if someone at the floor wants to enter the lift */ for (i = 0; i < MAX_N_PERSONS; i++) { tmp_id = Lift->persons_to_enter[Lift->floor][i].id; tmp_to_floor = Lift->persons_to_enter[Lift->floor][i].to_floor; if (tmp_id != NO_ID) { if (!enter_lift(Lift, Lift->persons_to_enter[Lift->floor][i].id, Lift->floor, Lift->persons_to_enter[Lift->floor][i].to_floor)) { break; } } } change_direction = !Lift->floor || Lift->floor == N_FLOORS-1; next_floor = change_direction ^ Lift->up ? Lift->floor-1 : Lift->floor+1; Lift->moving = 0; /* check if direction shall be changed */ if (change_direction) { Lift->up = !Lift->up; } Lift->floor = next_floor; Lift->moving = 1; } else if (len == sizeof(struct long_lift_msg)) { // We know that this is a LIFT_TRAVEL message // Update the trip list for the person that sent the message. long_m = (struct long_lift_msg *) msgbuf; tmp_id = long_m->person_id; trip_len[tmp_id] = long_m->trip_len; // printf("Received a long message from %d.\n Floors:", tmp_id); for (i=0; i < long_m->trip_len; i++) { to_floor_list[tmp_id][i] = long_m->to_floor[i]; from_floor_list[tmp_id][i] = long_m->from_floor[i]; // printf("(%lld, %lld), ", from_floor_list[tmp_id][i], to_floor_list[tmp_id][i]); } //printf("\n"); iterations[tmp_id] = 0; // Start timing for that person gettimeofday(&starttime[tmp_id][iterations[tmp_id]], NULL); // Make person enter lift enter_floor(Lift, tmp_id, from_floor_list[tmp_id][0], to_floor_list[tmp_id][0]); } } return; }
static void lift_process(void) { lift_type Lift; Lift = lift_create(); int change_direction, next_floor; int temp_id; int temp_to_floor; int to_floors_all[MAX_N_PERSONS][NUMBER_MESSAGES]; int from_floors_all[MAX_N_PERSONS][NUMBER_MESSAGES]; int person_message_iterator[MAX_N_PERSONS]; char msgbuf[4096]; while(1){ int i; struct lift_msg reply; struct lift_msg *m; //message_send((char *) Lift, sizeof(*Lift), QUEUE_UI,0); // Draw the lift int len = message_receive(msgbuf, 4096, QUEUE_LIFT); // Wait for a message if(len < sizeof(struct lift_msg)){ fprintf(stderr, "Message too short\n"); continue; } m = (struct lift_msg *) msgbuf; switch(m->type){ case LIFT_MOVE: for (i = 0; i < MAX_N_PASSENGERS; i ++){ if (Lift->passengers_in_lift[i].id != NO_ID){ if(Lift->passengers_in_lift[i].to_floor == Lift->floor){ temp_id = Lift->passengers_in_lift[i].id; Lift->passengers_in_lift[i].id = NO_ID; Lift->passengers_in_lift[i].to_floor = NO_FLOOR; if(person_message_iterator[temp_id] < NUMBER_MESSAGES){ enter_floor(Lift,temp_id,from_floors_all[temp_id][person_message_iterator[temp_id]],to_floors_all[temp_id][person_message_iterator[temp_id]]); //message_send((char *) Lift, sizeof(*Lift), QUEUE_UI,0); // Draw the lift person_message_iterator[temp_id]++; }else{ reply.type = LIFT_TRAVEL_DONE; //message_send((char *) Lift, sizeof(*Lift), QUEUE_UI,0); // Draw the lift message_send(&reply, sizeof(reply), QUEUE_FIRSTPERSON + temp_id, 0); } } } } /* Check if passengers want to enter the lift */ for (i = 0; i < MAX_N_PERSONS; i ++){ temp_id = Lift->persons_to_enter[Lift->floor][i].id; temp_to_floor = Lift->persons_to_enter[Lift->floor][i].to_floor; if ((temp_id != NO_ID) && n_passengers_in_lift(Lift) < MAX_N_PASSENGERS){ leave_floor(Lift, temp_id, Lift->floor); enter_lift(Lift, temp_id, temp_to_floor); //message_send((char *) Lift, sizeof(*Lift), QUEUE_UI,0); // Draw the lift } } lift_next_floor(Lift, &next_floor, &change_direction); lift_move(Lift, next_floor, change_direction); break; case LIFT_TRAVEL: for(i = 0; i < NUMBER_MESSAGES; i++){ to_floors_all[m->person_id][i] = m->to_floor[i]; from_floors_all[m->person_id][i] = m->from_floor[i]; } person_message_iterator[m->person_id] = 1; enter_floor(Lift, m->person_id, m->from_floor[0], m->to_floor[0]); //message_send((char *) Lift, sizeof(*Lift), QUEUE_UI,0); // Draw the lift break; } } return; }
static void lift_process(void) { lift_type Lift; Lift = lift_create(); int change_direction, next_floor; char msgbuf[4096]; struct lift_msg travel_list[MAX_N_PERSONS]; while(1){ int i; struct lift_msg reply; struct lift_msg *m; int len = message_receive(msgbuf, 4096, QUEUE_LIFT); // Wait for a message if(len < sizeof(struct lift_msg)){ fprintf(stderr, "Message too short\n"); continue; } m = (struct lift_msg *) msgbuf; for(i = 0; i < MAX_N_PASSENGERS; i++){ if (Lift->passengers_in_lift[i].to_floor == Lift->floor) { int id = Lift->passengers_in_lift[i].id; //fprintf(stderr,"ID is: %d\n",id); (travel_list[id].trip)++; //fprintf(stderr,"Trip is: %d\n", travel_list[id].trip); //message_send((char *) &reply, sizeof(reply), QUEUE_FIRSTPERSON + Lift->passengers_in_lift[i].id ,0); /*for(j = 0; j < MAX_N_PASSENGERS; j++){ fprintf(stderr, "before removing passengers_in_lift[%d].id = %d\n", j, Lift->passengers_in_lift[j].id); }*/ Lift->passengers_in_lift[i].id = NO_ID; Lift->passengers_in_lift[i].to_floor = NO_FLOOR; if(travel_list[id].trip == PLANNED_TRIPS){ message_send((char *) &reply, sizeof(reply), QUEUE_FIRSTPERSON + id ,0); //travel_list[id].trip = 0; //fprintf(stderr,"inne i skicka meddelande\n"); /*for(j = 0; j < MAX_N_PASSENGERS; j++){ fprintf(stderr, "passengers_in_lift[%d].id = %d\n", j, Lift->passengers_in_lift[j].id); }*/ } else if(travel_list[id].trip > PLANNED_TRIPS){ //fprintf(stderr, "IASFHFHKUEFHKSFH\n"); /*for(j = 0; j < MAX_N_PASSENGERS; j++){ fprintf(stderr, "passengers_in_lift[%d].id = %d\n", j, Lift->passengers_in_lift[j].id); }*/ exit(1); } else{ enter_floor(Lift, id, travel_list[id].from_floor[travel_list[id].trip], travel_list[id].to_floor[travel_list[id].trip]); //fprintf(stderr,"next trip here\n"); } } } // Check if passengers want to enter elevator // Remove the passenger from the floor and into the elevator for(i = 0; i < MAX_N_PERSONS; i++){ person_data_type person = Lift->persons_to_enter[Lift->floor][i]; if (person.id != NO_ID && (n_passengers_in_lift(Lift) < MAX_N_PASSENGERS)) { //fprintf(stderr,"Going to enter lift\n"); leave_floor(Lift, person.id, Lift->floor); enter_lift(Lift, person.id, person.to_floor); } } // Move the lift lift_next_floor(Lift, &next_floor, &change_direction); lift_move(Lift, next_floor, change_direction); break; case LIFT_TRAVEL: // TODO: // Update the Lift structure so that the person with the given ID is now present on the floor travel_list[m->person_id]=*m; enter_floor(Lift, m->person_id, m->from_floor[0], m->to_floor[0]); break; default: fprintf(stderr, "Error: unkown message type sent!!!!! \n"); break; } }
static void lift_process(void) { lift_type Lift; Lift = lift_create(); int change_direction, next_floor, tmp_id; struct lift_msg done_m; done_m.type = LIFT_TRAVEL_DONE; char msgbuf[4096]; while(1) { int i; struct lift_msg reply; struct lift_msg *m; message_send((char *) Lift, sizeof(*Lift), QUEUE_UI, 0); // Draw the lift int len = message_receive(msgbuf, 4096, QUEUE_LIFT); // Wait for a message if(len < sizeof(struct lift_msg)) { fprintf(stderr, "Message too short\n"); continue; } m = (struct lift_msg *) msgbuf; switch(m->type){ case LIFT_MOVE: // TODO: // Check if passengers want to leave elevator // Remove the passenger from the elevator // Send a LIFT_TRAVEL_DONE for each passenger that leaves // the elevator // Check if passengers want to enter elevator // Remove the passenger from the floor and into the elevator // Move the Lift‰ for (i = 0; i < MAX_N_PASSENGERS; i++) { if (Lift->passengers_in_lift[i].id != NO_ID && Lift->passengers_in_lift[i].to_floor == Lift->floor) { tmp_id = Lift->passengers_in_lift[i].id; leave_lift(Lift, tmp_id, Lift->passengers_in_lift[i].to_floor); message_send((char *) &done_m, sizeof(done_m), QUEUE_FIRSTPERSON + tmp_id, 0); } } for (i = 0; i < MAX_N_PERSONS; i++) { if (Lift->persons_to_enter[Lift->floor][i].id != NO_ID) { if (!enter_lift(Lift, Lift->persons_to_enter[Lift->floor][i].id, Lift->floor, Lift->persons_to_enter[Lift->floor][i].to_floor)) { break; } } } change_direction = !Lift->floor || Lift->floor == N_FLOORS-1; next_floor = change_direction ^ Lift->up ? Lift->floor-1 : Lift->floor+1; Lift->moving = 0; /* check if direction shall be changed */ if (change_direction) { Lift->up = !Lift->up; } Lift->floor = next_floor; Lift->moving = 1; break; case LIFT_TRAVEL: // TODO: // Update the Lift structure so that the person with the given ID is now present on the floor enter_floor(Lift, m->person_id, m->from_floor, m->to_floor); break; } } return; }