Figure Dining shows the corresponding HTML markup for the first page. We use two <app> tags to include inline applets written in Tcl/Tk. Note that text inside the open and close tag will be ignored by our browser and may be used to display warnings if the page is browsed by non-hush browsers as Mosaic or Netscape.
<title>The Dining Philosophers<title> <h1>The Dining Philosophers<h1> <h2>The problem<h2> Five philosophers sit around a table, with five chopsticks in between. ... We are interested in <a href="results.html">the percentage of the time<a> a philosopher actually thinks. <app class="sim-setup"> Error: Dining table deleted: use our hush browser! </app> <hr> Press this button: <app class="sim-button"> Error: Run button deleted: use our hush browser! </app>
The Tcl/Tk applets used in the example above are in fact only responsible for the graphical interface, the simulation itself is modeled in C++, by refining the entity class (modeling a philosopher) and the resource class (modeling a chopstick) of the simulation library.
The simulation is initialized by scheduling five philosopher entity objects in a "waiting" phase at time t=0.0. The "simulation init" command will be executed by first applet. The simulation can be started by executing the "simulation run" command, which is bound on a push button by the sim-button applet.
When a philosopher is due to be activated, the scheduler will call its application operator which will perform an explicit dispatch on the current phase:
int philosopher::operator()() { switch (phase()){ case EATING : eat(); return OK; case THINKING : think(); return OK; case WAITING : await(); return OK; default: return FALSE; // undefined phase } }
Suppose the philosopher is still in a waiting phase. The await() member will be called and the philosopher will see whether his chopsticks are available. If so, she will acquire them and starts eating. If not, the philosopher will remain in a waiting state, but is put on the scheduler's list of conditional events.
void philosopher::await() { if (chopsticks_available()) { acquirechopsticks(); phase(EATING); } else if (!conditional()) { waitonchopsticks(); sim->hold(this); } }
However, if the philosopher is invoked while she is in a eating phase, she will continue with eating for some (exponentially distributed) random time interval after which she will move to a "thinking" phase.
void philosopher::eat() { double t = gen->exponential(EAT_TIME); phase(THINKING); sim->wait(t); }
In addition, we extended the simulation package with a soft-real time option, that allows us to schedule clock-synchronized events. For example, we implemented a simple slide show, by the repetitive scheduling of HTML pages with a fixed time interval.
However, general hypermedia applications require support for far more complex synchronization relations and temporal dependencies between the components of a hypermedia document. Such high-level temporal alignment cannot be (easily) expressed using the basic simulation primitives, nor can the corresponding documents be expressed by (text oriented) markup languages as HTML.
Therefor, we are currently developing components supporting more complex scheduling primitives. One of our goals is to add a (subset of) the event scheduling mechanisms of HyTime [REFXXX] to our new, SGML-based Web widget.