[Squeak-e] adding eventual sending to Croquet's ScriptProcessandScriptScheduler

Andreas Raab andreas.raab at gmx.de
Sun Feb 16 23:00:38 CET 2003


The most important thing first:
> Ok, that works, but how is that guaranteed?

Yes, yes, and yes. It is THE fundamental invariant. Scripts are only
interrupted if they block. #startScript: is non-blocking. Period. What
follows are mere details of how this is implemented ;-)

[Note: Read up to the end of the message before replying - various questions
might be answered further down the line]

> I have a few questions.  I don't think this is a good thing for the 
> eventual event-loop.  This is interrupting the current script and I 
> don't think there are any guarantees that the currentScript 
> will be the first script resumed after the new script is scheduled.
> Is there?

As far as the "user script" (namely: the payload of the process) is
concerned, #startScript: is immediate (non-blocking). It is the
implementation of the synchronization semantics which will temporarily
suspend the invoking user script but do so in a way that it is invisible
from the client. The implementation essentially does:

* script1 issues #startScript:
===== system level ====
this is where the synchronization semantics starts. in order to preserve
ordering of scripts the following happens:
  * #startScript: creates a new script (script2) with a higher(!) priority
than script1 (Processor>>initialScriptPriority)
  * script2 preempts script1
  * script2 schedules itself with the scheduler
  * script2 suspends itself (in scheduler's activeList)
===== user level =====
* script1 continues happily as if never interrupted
[... some time later ...]
* script2 gets its slot
===== system level ====
  * script2 resets its priority down(!) to regular user script priority
===== user level ====
* script2 delivers payload

To get the scheduling semantics right, I am playing with process priorities.
As long as scripts are "out in the wild" (that is: not controlled by the
script processor) they run at higher priority. This happens only in two
places: Immediately after their creation (in which case they need to
schedule themselves) or inside "primitive waits". In both cases the priority
is bumped up in order to ensure that there can be only a single script "out
in the wild" and that this script reschedules itself as quickly as it can
with the script scheduler. [Slight OT: There *is* a chance that two scripts
are "in the wild" if both get released after waiting on a semaphore.
However, in this case the user code cannot decide "which one was first" so
ordering does not matter. For issuing #startScript: however, this will never
happen, since #startScript: is only issued from scripts which aren't "out in
the wild"].

There are many, many subtleties in this regime. I went to great length to
make this work "just right".

> There  may be a third script which is scheduled ahead of the 
> currentScript.

No. There is no way that this can happen. Literally. The scheduler process
even runs at a lower priority than the script processes (once more:
priorities are our friends ;) in order to ensure that a new script is only
scheduled if the current script is blocking or completed. Using priorities
ensures this invariant primitively and avoids needless synchronization of

> How does the suspension of a script schedule 
> the script for resumption?

The script reschedules itself. When a script blocks, it always waits on some
semaphore (this is the only way any process in Squeak can block). When this
happens, the hooks within #beginWaitOn: and #endWaitOn: kick in. They
provide the appropriate rescheduling semantics by bumping the priority up
for the wait (the script is now "in the wild" since we don't know when it
will become resumed primitively) and rescheduling itself (and reducing the
priority) once it wakes up again.

One exception: Scripts inside critical sections *must* be run in the wild.
The reason being that we would deadlock otherwise (I tried it ;)

> Is there no way to schedule the
> new script without making it the activeScript?

You never schedule a new script and "automatically" make it the active
script. When you schedule a script then (as the name "scheduling" says) its
get added to the list of scripts that may be run as soon as the current one
completes. Or do you mean "without adding it to the activeList"?!

  - Andreas

More information about the Squeak-e mailing list