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.