On Sat, 11 Jan 2020 at 18:01, ducasse <steph...@netcourrier.com> wrote:
> > > On 11 Jan 2020, at 10:50, Ben Coman <b...@openinworld.com> wrote: > > > > On Sat, 11 Jan 2020 at 06:31, Sven Van Caekenberghe <s...@stfx.eu> wrote: > >> Hi Ben, >> >> Great approach, though I would make one change to make your example >> completely copy/paste runnable. >> >> Stef's original example: >> >> | trace semaphore p1 p2 | >> >> semaphore := Semaphore new. >> >> trace := [ :message | >> ('[{1}] {2}' format: { Processor activeProcess priority. message >> }) crLog ]. >> >> p1 := [ >> semaphore wait. >> trace value: 'Process 1' ] fork. >> >> p2 := [ >> semaphore signal. >> trace value: 'Process 2' ] fork. >> >> trace value: 'Original process pre-yield'. >> Processor yield. >> trace value: 'Original process post-yield'. >> >> Gives: >> >> '[40] Original process pre-yield' >> '[40] Process 2' >> '[40] Original process post-yield' >> '[40] Process 1' >> >> But not running the yield section gives: > > >> '[40] Process 2' >> '[40] Process 1' >> > > which is an identical result if the 'Original process' traces are filtered > out. > > > >> From this it would seem that the code in p2 continues after signal and >> only later does p1 get past its wait. >> > > Yes, a #signal does not transfer execution unless the waiting-process that > received the signal is a higher priority. > Within the same priority, it just makes waiting-process runnable, and the > highest-priority-runnable-process is the one that is run. > > > > Playing with the priorities we can change that order (apparently); >> >> | trace semaphore p1 p2 | >> >> semaphore := Semaphore new. >> >> trace := [ :message | >> ('[{1}] {2}' format: { Processor activeProcess priority. message >> }) crLog ]. >> >> p1 := [ >> semaphore wait. >> trace value: 'Process 1' ] forkAt: 30. >> >> p2 := [ >> semaphore signal. >> trace value: 'Process 2' ] forkAt: 20. >> >> Gives: >> >> '[30] Process 1' >> '[20] Process 2' >> >> Again, the yield section makes no difference. So something else happened. >> > > The yield made no difference because it only facilitates other processes > at-the-SAME-priority getting a chance to run. > Yield doesn't put the current-process to sleep, it just moves the process > to the back of its-priority-runQueue. It gets to run again before any lower > priority process gets a chance to run. > > Yielding will never allow a lower-priority-process to run. > For a lower-priority process to run, the current-process needs to sleep > rather than yield. > > > Indeed. I will add this note to my chapter. > > > Compare... > | trace semaphore p1 p2 | > semaphore := Semaphore new. > trace := [ :message | ('@{1} {2}' format: { Processor activePriority. > message }) crLog ]. > p1 := [ > trace value: 'Process 1a waits for signal on semaphore'. > semaphore wait. > trace value: 'Process 1b received signal' ] forkAt: 30. > p2 := [ > trace value: 'Process 2a signals semaphore'. > semaphore signal. > trace value: 'Process 2b continues' ] forkAt: 20. > trace value: 'Original process pre-yield'. > Processor yield. > trace value: 'Original process post-yield'. > > ==> > '@40 Original process pre-yield' > '@40 Original process post-yield' > '@30 Process 1a waits for signal on semaphore' > '@20 Process 2a signals semaphore' > '@30 Process 1b received signal' > '@20 Process 2b continues' > > with... > | trace semaphore p1 p2 | > semaphore := Semaphore new. > trace := [ :message | ('@{1} {2}' format: { Processor activePriority. > message }) crLog ]. > p1 := [ > trace value: 'Process 1a waits for signal on semaphore'. > semaphore wait. > trace value: 'Process 1b received signal' ] forkAt: 30. > p2 := [ > trace value: 'Process 2a signals semaphore'. > semaphore signal. > trace value: 'Process 2b continues' ] forkAt: 20. > trace value: 'Original process pre-delay'. > 1 milliSecond wait. > trace value: 'Original process post-delay'. > > ==> > '@40 Original process pre-delay' > '@30 Process 1a waits for signal on semaphore' > '@20 Process 2a signals semaphore' > '@30 Process 1b received signal' > '@20 Process 2b continues' > '@40 Original process post-delay' > > > > Stef, on further consideration I think your first examples should not-have > p1 and p2 the same priority. > Scheduling of same-priority processes and how they interact with the UI > thread is an extra level of complexity that may be better done shortly > after. > > > Yes I realize it. > > Not needing to trace "Original process" in the first example gives less > for the reader to digest > > > Yes I thought the same. > I thought that I could have the following strategy. > Give a first simple version, them revisiting it after. > At first glance I thought using #fork would a simpler example than using #forkAt:, but the former interacts with the implicit priority of existing UI process, while the latter is explicit and so actually makes a simpler example. cheers -ben