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.
