[Vm-dev] Re: The serverMode flag and some thoughts on event polling
andreas.raab at gmx.de
Fri Aug 26 15:48:20 UTC 2011
Hi Dimitry -
On 8/25/2011 19:01, Dimitry Golubovsky wrote:
> In order to port Cog to Android, I turned it into an event-driven VM
> based on ideas found in . 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.
I think that relying exclusively on relinquishProcessor is a mistake.
It's a fine approach for situations where there is low CPU utilization
and relinquishProcessor is called often, but it doesn't really work
under high load.
Rather than relying on relinquishProcessor implicitly, I would suggest
you either change (or add another) primitive that such that ioRelinquish
always executes the return to the OS. This is advantageous to the
serverMode flag (which for other reasons is somewhat silly) as you can
modify the Morphic base loops to Do The Right Thing, for example by
adding the primitiveRelinquish to WorldState>>interCyclePause. This
means that even if there is more computational power needed than there
is available (in other words, relinquishProcessor never gets called from
the idle loop) you are making sure that you do get back to the OS at
well-defined points (such as after completing a Morphic cycle) which
prevents the OS from thinking we're non-responsive.
> The serverMode flag  (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).
But this only works if your UI is eating up all the cycles. If, for
example, you have a simulation running at lower (or higher) priority,
Android will still think that the app is dead. That's why the explicit
relinquish primitive is advantageous from my point of view - it gives
you control over when and where to hand back control.
> 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.
With an explicit relinquish primitive you can 'fix' those loops simply
by inserting a "Processor relinquishProcessor" or somesuch. It might be
better to rewrite code like the above entirely, but at the very least
you have an easy workaround.
> 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?
Almost certainly, yes. Historically, the way to grab modal input used to
be along the lines of, e.g., "[Sensor anyButtonPressed] whileTrue" and
there are definitely more packages out there that do stuff like it.
> 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?
Absolutely. One just needs to write the proper code :-)
> 2. Are there images in active development (other than PharoCore, and
> Squeak) where event polling is done without an option to relinquish
Yes. But likely nobody will want to run these in unmodified form on
Android so I wouldn't worry about too much about it.
More information about the Vm-dev