[squeak-dev] Events in HydraVM

Igor Stasenko siguctua at gmail.com
Thu Feb 28 19:33:30 UTC 2008


2008/2/28 Stephan Rudlof <sr at evolgo.de>:
> Hello Igor,
>
>  thank you for your interesting explanations!
>
>  One remark:
>
>
>  On 28.02.2008 09:04, Igor Stasenko wrote:
>  > John M McIntosh asked me to make some overview on HydraVM internals -
>  > events subsystem.
>  > So, here it is. :)
>  >
>  >...
>
> > About event handling function:
>  > this is the function which will be called when interpreter will
>  > interrupt for handling events, so in this function you have
>  > synchronized access to object memory, interpreter state e.t.c. and
>  > don't have to worry about concurrency.
>  > Also, function along with event payload are very convenient for
>  > determining context and what event means and what it will do.
>
>  > Instead of making dozens of event types, enumerating them.. then
>  > writing a case statements, it's doing a simple dispatch
>  > event->fn(interpreter, event); so, system are flexible and can handle
>  > events of any kind doing anything you want.
>
>  This makes it possible to elegantly switch between different event handling funcs: e.g. between a normal and a debugging one, without *any* debugging code in the normal one (by an event func var in the plugin, set by a plugin primitive, used by event posting code).
>
Good idea.
I'm already used function switching in single place, but for different
reason (quirk).

Also, i forgot to mention, that in some places events are allocated
statically (or at initializing of plugin), to not use malloc/free
patterns everytime.

This approach is more safer, in a way that you can control different
aspects of event generation: prevent queue overruns for example (when
VM can't handle events at speed they generated).
A pattern is simple:
use static buffer, or preallocated one, ruled by event queue.
So, when we need to generate new event, instead of using heap (don't
forget it's time consuming too), we can do following:

vmEventQueue unusedEvents; // a queue of unused events, initially
filled with pointers to preallocated buffer space

Generating event:

myEvent * event = ioDequeueEventFrom(&unusedEvents);
if (!event)
{
 // unused event queue is empty, this means that VM still was unable
to handle events in time

 // if this code runs in separate native thread, we simply can wait for free one
 do
  {
   sleep(1 ms);
  }   while (0 == (event = ioDequeueEventFrom(&unusedEvents)));

// or, if we can't see a reason why events are still didn't handled,
then something is really wrong with design, so generate error
  error("this should never happen");

}
event->header->fn = myHandler;
event->myField1 = ...
enqueueEvent(intr,myEvent);


And in event handling function, we simply return event to it's queue:

sqInt myHandler(struct Interpreter * intr, myEvent * evt)
{
  .....

 ioEnqueueEventInto(evt, &unusedEvents); // put event back to unused event queue
}



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list