Consider the following definition and implementation of the entity philosopher
enum {EATING,THINKING,WAITING}; // phases of a philosopher class philosopher : public entity { public : philosopher(int ph,int i); // constructor, taking phase and id virtual int operator()(); // function operator int eat(); // eat event int think(); // think event int await(); // await event private : int id; generator* g; }; philosopher::philosopher(int ph,int i) : entity(ph) { id = i; // set phase and identity g = new generator(20,10,999); } int philosopher::operator()() { switch (phase()) // what phase is the philosopher in ? { case EATING : return eat(); // the philosopher eats case THINKING : return think(); // the philosopher thinks case WAITING : return await(); // the philosopher waits } return FALSE; } int philosopher::eat() { double t = g -> exponential(eatingtime); // determine eating time sim -> wait(t); // schedule this philosopher thinking phase(THINKING); // set phase to thinking return OK; } int philosopher::think() { chopstick[id] -> release(); // release left chopstick chopstick[(id+1)%number] -> release(); // release right double t = g -> exponential(thinkingtime); // determine thinking time thinking -> sample(id,t/duration*100); // sample (%) sim -> wait(t); // schedule this philosopher waiting phase(WAITING); // set phase on waiting return OK; } int philosopher::await() { if ( (chopstick[id] -> available()) && // available ? (chopstick[(id+1)%number] -> available()) ) { chopstick[id] -> acquire(); // acquire left chopstick chopstick[(id+1)%number] -> acquire(); // acquire right sim -> passivate(this); // make passive sim -> activate(this); // activate as eating phase(EATING); // set phase on eating } else if (!conditional()) sim -> hold(this); // add to conditional return OK; }
Dependent on the phase the philosopher is in, the appropriate action on the simulation environment is taken. These actions closely resemble the events, described in the event-based approach of this problem. The main difference is in the use of phase. If, for example, a philosopher finishes eating, his/her phase is set to THINKING and s/he is scheduled after t time units, whereas in the event-based approach a think event is scheduled and the eat event is explicitly terminated. So, in the process-oriented solution a philosopher exists for the entire simulation. In the session::main function the simulation is set up by scheduling the five philosophers, initially waiting, instead of scheduling five await events.