/* 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); } }
/* returns 1 if successful */ int enter_lift(lift_type lift, int id, int from_floor, int to_floor) { int found = 0; int lift_index = 0; int i; /* enter el lifto */ for (i = 0; i < MAX_N_PASSENGERS && !found; i++) { if (lift->passengers_in_lift[i].id == NO_ID) { found = 1; lift_index = i; } } if (!found) { printf("I'm number %d. I cannot enter the lift so I guess I'll just stand here.\n", id); return 0; } // Move person into lift =) lift->passengers_in_lift[lift_index].id = id; lift->passengers_in_lift[lift_index].to_floor = to_floor; leave_floor(lift, id, from_floor); return 1; }
/* 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; 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; } }