On Sun, 12 Jan 2020 at 20:00, Sven Van Caekenberghe <[email protected]> wrote:

> Hi Alistair,
>
> > On 12 Jan 2020, at 09:33, Alistair Grant <[email protected]> wrote:
> >
> > On Thu, 9 Jan 2020 at 13:01, ducasse <[email protected]> wrote:
> >>
> >> Hi
> >>
> >> I wanted to explain
> >>
> >> | semaphore p1 p2 |
> >> semaphore := Semaphore new.
> >> p1 := [ semaphore wait.
> >>        'p1' crTrace ] fork.
> >>
> >> p2 := [semaphore signal.
> >>         'p2' crTrace ] fork.
> >>
> >> displays p2 and p1.
> >> but I would like explain clearly but it depends on the semantics of
> signal.
> >
> > The way this is phrased seems to imply that 'p2' will always be
> > displayed before 'p1', however in Pharo this is not guaranteed (when
> > the processes are at the same priority, as they are this example).
> >
> > As Eliot implied in another reply, Pharo has #processPreemptionYields
> > set to true, which means that any time a higher priority process
> > preempts, the current process will be moved to the back of the queue.
> >
> > So in the case above, after p2 signals the semaphore, if a timer was
> > delivered or keystroke pressed, p2 would be suspended and moved to the
> > back of the queue.  When the timer / keystroke / etc. had finished
> > processing p1 would be at the front of the queue and would complete
> > first.
> >
> > Since time and input events are (for practical purposes) unpredictable
> > it means that the execution order of processes at a given priority is
> > also unpredictable.
> >
> > While this isn't likely to happen in the example above, I have seen it
> > regularly with TaskIt and multiple entries being run concurrently.
> >
> > I agree with Eliot that changing #processPreemptionYields to true by
> > default would be an improvement in Pharo.  It would make it easier to
> > predict what is happening in a complex environment.
>
> I don't understand, in your second paragraph you say 'Pharo has
> #processPreemptionYields set to true' and now you say it should become the
> default. Is that already the case or not then ?


> > Running the following variant, and then typing in to another window,
> > demonstrates the behaviour:
>
> I am not sure what you want to demonstrate: that it is totally random
> depending on external factors ;-) ?
>
> Which is pretty bad: how should semaphores be used (safely) ? What are
> good examples of real world correct semaphore usage ?
>

Bad depends on the assumptions you are working with.
The issue is its generally promoted that our scheduling is
"preemptive-across-priorities, cooperative-within-priorities"
but thats not entirely true for Pharo, which is
"preemptive-across-priorities, mostly-cooperative-within-priorities".

The former is arguably a simpler model to reason about, and having
consistent implicit-behaviour between same-priority-processes lessens the
need for Semaphores between them.
However if you naively "assume" the former you may get burnt in Pharo since
behaviour between same-priority-processes is random
depending on "when" higher priority processes are scheduled.

But if you "assume" the latter (i.e. that your process can be preempted any
time) you'd use Semaphores as-needed and have no problems.
So to reply directly to your last line. Semaphores can always be used
safely.  Its poor assumptions about when Semaphores aren't required that is
bad.


Now a new consideration for whether Pharo might change the default
processPreemptionYields to false
is ThreadedFFI.  Presumably it will be common for a callback to be defined
at same priority as an in-image process.
I can't quite think through the implications myself.
So a question... if a callback is a lower-priority than the current
process, does it wait before grabbing the VM lock (IIUC how that is meant
to work)?



> Right now, all the explanations around scheduling of processes and their
> priorities make it seem as if the answer is 'it all depends' and 'there is
> no way to be 100% sure what will happen'.
>

Reasoning about processes at different-priorities its easy and explicit.
Between processes at the same-priority you are correct, currently 'there is
no way to be 100% sure what will happen' (without Semaphores).
Examples showing same-priority processes interacting like its cooperative
will lead to student confusion when their results differ from the book.
Currently Pharo must be taught with examples presuming a fully preemptive
system (at restricted locations like backward jumps).

cheers -ben

P.S. Now I wonder about the impact of upcoming Idle-VM.  Currently
same-priority-processes are effectively round-robin scheduled
because the high priority DelayScheduler triggers often, bumping the
current process to the back of its runQueue.
When it triggers less often, anything relying on this implicit behaviour
may act differently.

Reply via email to