[Vm-dev] The serverMode flag and some thoughts on event polling

Dimitry Golubovsky golubovsky at gmail.com
Thu Aug 25 17:01:10 UTC 2011


[this is not really about VM alone, but rather how image and VM
interact - hence posting to multiple lists]

In the process of porting Cog to Android, I observed the following
pattern. If a scrollbar's "up" or "down" button is held pressed
(prolonged tap on a button) for few seconds, the VM freezes, and gets
killed by Android. Digging down the code got me to the
WorldState>>interCyclePause: method. When there are morphs requesting
stepping by shorter than certain time interval, the process
responsibke for running step methods keeps looping without giving up
to lower priority processes (and the host OS). ScrollBar seems to
decrease the stepping interval over time to simulate accelerated

In order to port Cog to Android, I turned it into an event-driven VM
based on ideas found in [1]. The same was done by Andreas for his
earlier Classic VM port. My approach is a bit different such as the
longjmp call is made as part of the relinquishProcessor primitive.
Such primitive is called only from the lowest priority (idle) process
which only can run when there are no external events to deal with. The
event-driven VM needs to exit from the interpreter to the host process
in order to obtain any input events. Thus, non-interrupted polling
just deadlocks the interpreter as it cannot exit to the host process
to get more events, yet keeps polling for them.

The serverMode flag [2] (aka Mantis #6581) came to rescue. With such
flag set to true, polling for events always yields CPU for 50ms (which
in the Android case is meaningless anyway: I would not give the VM
idle timer more often than 10 times per sec, so 50ms granularity is
just not handleable). Anyway this does the trick as the lowest
priority process gets its CPU time, and exits the interpreter to the
host process. With serverMode = true I can tap a scroller button as
long as I want, and even the text cursor in a workspace keeps blinking
which means that stepping works and VM is alive. BTW in Android, the
interpreter will be called as soon as any user action is intercepted,
so responsiveness is not degraded regardless of the delay introduced
by serverMode.

I have found at least one place (this is in PharoCore) where
serverMode is not honored: PolygonMorph class >> fromHand: (this
method creates a polygon drawn by the mouse)

This method has code pieces (repeating multiple times btw - why is it
not a separate method?)

[Sensor anyButtonPressed] whileFalse:
  			[self currentWorld displayWorldSafely; runStepMethods].

which is clearly grabbing the event sensor to the polygon morph while
keeping other morphs stepped, so the VM does not seem dead entirely.
In my case though executing PolygonMorph fromHand: defaultHand freezes
the VM immediately as this is uninterrupted polling again.

While I'll try to experiment with inserting interCyclePause somewhere
in these loops, there are broader questions on how event polling is
done these days:

1. Are there other morphs in packages not included in PharoCore where
event grabbing is done such way?

1a. Is this possible in general to have such functionality properly
embedded in WorldState instead of having it in a morph itself, if
event grabbing is needed?

2. Are there images in active development (other than PharoCore, and
Squeak) where event polling is done without an option to relinquish

In fact, this VM freezing on stepping morphs was a big issue, and it
mainly kept me from moving towards the public release. Now that it
seems to be solved (unless there is a flaw in my logic above) it takes
me closer to finishing the Cog for Android port.


[1] http://lists.squeakfoundation.org/pipermail/vm-dev/2009-November/003385.html
[2] http://bugs.squeak.org/view.php?id=6581

Dimitry Golubovsky

Anywhere on the Web

More information about the Vm-dev mailing list