/* dining.c */ #include "asm.h" #include "dining.h" #include "scheduler.h" #include "string.h" #include "process.h" #include "message.h" #include "tty3.h" void dining() { char args[2][MAX_STR_LEN]; int waiter_pid = new_p("waiter", args); int i; for (i = 0; i < PHILS; i++) { int_to_string(args[0], waiter_pid); new_p("phil", args); } terminate(get_running() + 1); } void end_dinner(int waiter_pid, int eat_log[]) { int i; for (i = waiter_pid + 1; i < waiter_pid + PHILS; i++) { terminate(i); } for (i = 0; i < PHILS; i++) { print_int(i + 1); print_string(" ate "); print_int(eat_log[i]); print_string(" times.\n"); } terminate(waiter_pid); } void waiter() { int food = 5; int id = get_running(); int pid = id + 1; int free_forks[FORKS]; int eat_log[PHILS]; int i; for(i = 0; i < FORKS; i++) { free_forks[i] = 1; eat_log[i] = 0; } while(1) { if (receive_message()) { int from_pid = PCB_list[id].current_message.sender_pid; int left_fork = from_pid - pid - 1; int right_fork = left_fork - 1; if (right_fork == -1) { right_fork = FORKS - 1; } if (name_comp(PCB_list[id].current_message.data, "done")) { eat_log[from_pid - pid - 1]++; if (!(food--)) { end_dinner(pid, eat_log); } free_forks[left_fork] = 1; free_forks[right_fork] = 1; } else if (name_comp(PCB_list[id].current_message.data, "left")) { if (free_forks[left_fork] && check_forks(free_forks)) { free_forks[left_fork] = 0; send_message("Left fork", 1, from_pid); } } else if (name_comp(PCB_list[id].current_message.data, "right")) { if (free_forks[right_fork] && check_forks(free_forks)) { free_forks[right_fork] = 0; send_message("Right fork", 1, from_pid); } } } } } int check_forks(int forks[]) { int sum = 0; int i; for(i = 0; i < FORKS; i++) { if (forks[i]) { sum++; } } if (sum > 1) { return 1; } else { return 0; } } void phil() { int id = get_running(); int pid = id + 1; int waiter_pid = string_to_int(PCB_list[id].arg_1); int phil_id = pid - waiter_pid; int state = THINK; while(1) { if (state == THINK) { hold_rand(pid); state = NO_FORK; print_int(phil_id); print_string(" wants to eat, but has no forks.\n"); } if (state == NO_FORK) { send_message("left", 1, waiter_pid); while(!receive_message()) ; print_int(phil_id); print_string(" wants to eat, but has only the left fork.\n"); state = LEFT_FORK; } if (state == LEFT_FORK) { send_message("right", 1, waiter_pid); while(!receive_message()) ; print_int(phil_id); print_string(" is eating.\n"); state = EAT; } if (state == EAT) { hold_rand(pid); send_message("done", 1, waiter_pid); print_int(phil_id); print_string(" is thinking.\n"); state = THINK; } } } void hold_rand(int pid) { int target = (int)get_timer() % 7; int its = 0; while(its++ < target) { hold(pid); } }