#include <utility/ostream.h>
#include <thread.h>
#include <semaphore.h>
#include <alarm.h>
#include <display.h>
__USING_SYS
const int iterations = 10;
const int thinking_time = 100000;
const int eating_time = 500000;
Semaphore sem_display;
Thread * phil[5];
Semaphore * chopstick[5];
OStream cout;
int philosopher(int n, int l, int c)
{
int first = (n < 4)? n : 0;
int second = (n < 4)? n + 1 : 4;
for(int i = iterations; i > 0; i--) {
sem_display.p();
Display::position(l, c);
cout << "thinking";
sem_display.v();
Delay thinking(thinking_time);
chopstick[first]->p(); chopstick[second]->p();
sem_display.p();
Display::position(l, c);
cout << " eating ";
sem_display.v();
Delay eating(eating_time);
chopstick[first]->v(); chopstick[second]->v(); }
sem_display.p();
Display::position(l, c);
cout << " done ";
sem_display.v();
return(iterations);
}
int main()
{
sem_display.p();
Display::clear();
cout << "The Philosopher's Dinner:\n";
for(int i = 0; i < 5; i++)
chopstick[i] = new Semaphore;
unsigned long sleep_time = iterations * (eating_time + thinking_time);
Thread::Criterion c0 = Thread::Criterion(sleep_time * 11, sleep_time * 2);
Thread::Criterion c1 = Thread::Criterion(sleep_time * 11, sleep_time * 2);
Thread::Criterion c2 = Thread::Criterion(sleep_time * 11, sleep_time * 2);
Thread::Criterion c3 = Thread::Criterion(sleep_time * 11, sleep_time * 2);
Thread::Criterion c4 = Thread::Criterion(sleep_time * 11, sleep_time * 2);
phil[0] = new Thread(&philosopher, 0, 5, 32, Thread::READY, c0);
phil[1] = new Thread(&philosopher, 1, 10, 44, Thread::READY, c1);
phil[2] = new Thread(&philosopher, 2, 16, 39, Thread::READY, c2);
phil[3] = new Thread(&philosopher, 3, 16, 24, Thread::READY, c3);
phil[4] = new Thread(&philosopher, 4, 10, 20, Thread::READY, c4);
cout << "Philosophers are alife and hungry!\n";
cout << "The dinner is served ...\n";
Display::position(7, 44);
cout << '/';
Display::position(13, 44);
cout << '\\';
Display::position(16, 35);
cout << '|';
Display::position(13, 27);
cout << '/';
Display::position(7, 27);
cout << '\\';
sem_display.v();
for(int i = 0; i < 5; i++) {
int ret = phil[i]->join();
sem_display.p();
Display::position(20 + i, 0);
cout << "Philosopher " << i << " ate " << ret << " times \n";
sem_display.v();
}
for(int i = 0; i < 5; i++)
delete chopstick[i];
for(int i = 0; i < 5; i++)
delete phil[i];
cout << "The end!\n";
return 0;
}