/* The task is to synchronise the code and avoid all kind of "busy-wait". The solution can and should replace relevant part of the code with locks and semaphores. (Coniditionals optional, if you prefer) There are: - 10 philosophers - A round table with 5 seats - A bowl of food in the middle of the table - 2 staff members that refills the bowl - A plate per seat, and a fork between each plate Requirements for eating: - Each philosopher needs a seat. - A philosopher needs the 2 forks next to their plate. - There has to be food in the bowl. - If the bowl is empty the philosopher leaves the table - A philosopher should be able to eat at the same time as other philosophers Note: The functions that are not defined can be assumed to be thread safe (synchronised) Remember, no deadlocks! */ // begin of dummy declarations that are only // designed to get the code through compiler typedef enum { false, true } bool; struct semaphore { int count; }; struct lock { int owner; }; struct condition { int placeholder; }; // The five functions are thread-safe. void cook_more_rations(); void eat_randomly_long_time(); void sleep_randomly_long_time(); void swap(int*, int*); void sema_init(struct semaphore*, int); void sema_down(struct semaphore*); void sema_up(struct semaphore*); void lock_init(struct lock*); void lock_acquire(struct lock*); void lock_release(struct lock*); void cond_init (struct condition*); void cond_wait (struct condition*, struct lock*); void cond_signal (struct condition*, struct lock*); int atomic_swap(int*, int); int test_and_set(int *); int compare_and_swap(int *, int, int); // end of dummy declarations bool seat_taken[5]; bool fork_taken[5]; int rations_of_food = 0; void init() // executed before threads { for (int i = 0; i < 5; ++i) { seat_taken[i] = false; fork_taken[i] = false; } } void clerk_thread() // two of those { for ( ; ; ) { // Add more food to table rations_of_food = rations_of_food + 1; cook_more_rations(); } } void philosopher_thread() // ten of those { for ( ; ; ) { int seat_no = 0; // Find a free seat. while ( seat_taken[seat_no] ) seat_no = (seat_no + 1) % 5; seat_taken[seat_no] = true; // Grab two forks. int fork1 = seat_no; int fork2 = (seat_no + 1) % 5; while ( fork_taken[fork1] ) ; fork_taken[fork1] = true; while ( fork_taken[fork2] ) ; fork_taken[fork2] = true; // Check for food. Eat, or leave hungry. if (rations_of_food > 0) { rations_of_food = rations_of_food - 1; eat_randomly_long_time(); } // Replace forks and leave seat. fork_taken[fork1] = false; fork_taken[fork2] = false; seat_taken[seat_no] = false; // Digest the food. sleep_randomly_long_time(); } }