<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small">Hi Jaromir, Hi Levente, Hi Vanessa, Hi All,</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Dec 28, 2021 at 11:55 AM <<a href="mailto:mail@jaromir.net">mail@jaromir.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Hi Eliot,<br>
<br>
Thanks! Please see my comments below, it seems to me there may be a bug in the Mutex.<br></blockquote><div><br></div><div class="gmail_default" style="font-size:small">Executive summary; AFAICT it is due to the bug in the suspend primitive. Specifics below, including two proposed fixes that need community review.</div><div class="gmail_default" style="font-size:small">[look for "<span style="color:rgb(0,0,0)">Should we change primitiveSuspend to the above?</span><span class="gmail-Apple-converted-space" style="color:rgb(0,0,0)">" and "</span><span style="color:rgb(0,0,0)">So let's look at the alternative</span><span style="color:rgb(0,0,0)">"]</span></div><div class="gmail_default" style="font-size:small"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">~~~<br>
^[^    Jaromir<br>
<br>
Sent from Squeak Inbox Talk<br>
<br>
On 2021-12-27T14:55:22-08:00, <a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a> wrote:<br>
<br>
> Hi Jaromir,<br>
> <br>
> On Mon, Dec 27, 2021 at 2:52 AM <mail at <a href="http://jaromir.net" rel="noreferrer" target="_blank">jaromir.net</a>> wrote:<br>
> <br>
> > Hi all,<br>
> ><br>
> > What is the desirable semantics of resuming a previously suspended process?<br>
> ><br>
> <br>
> That a process continue exactly as it had if it had not been suspended in<br>
> the first place.  In this regard our suspend is hopelessly broken for<br>
> processes that are waiting on condition variables. See below.<br>
> <br>
> <br>
> ><br>
> > #resume's comment says: "Allow the process that the receiver represents to<br>
> > continue. Put the receiver in *line to become the activeProcess*."<br>
> ><br>
> > The side-effect of this is that a terminating process can get resumed<br>
> > (unless suspendedContext is set to nil - see test KernelTests-jar.417 /<br>
> > Inbox - which has the unfortunate side-effect of #isTerminated answer true<br>
> > during termination).<br>
> ><br>
> <br>
> But a process that is terminating should not be resumable.  This should be<br>
> a non-issue.  If a process is terminating itself then it is the active<br>
> process, it has nil as its suspendedContext, and Processor<br>
> activeProcess resume always produces an error.. Any process that is not<br>
> terminating itself can be made to fail by having the machinery set the<br>
> suspendedContext to nil.<br>
> <br>
<br>
Yes agreed, but unfortunately that's precisely what is not happening in the current and previous #terminate and what I'm proposing in Kernel-jar.1437 - to set the suspendedContext to nil during termination, even before calling #releaseCriticalSection.<br>
<br>
> <br>
> > A similar side-effect: a process originally waiting on a semaphore and<br>
> > then suspended can be resumed into the runnable state and get scheduled,<br>
> > effectively escaping the semaphore wait.<br>
> ><br>
> <br>
> Right,  This is the bug.  So for example<br>
>     | s p |<br>
>     s *:=* Semaphore new.<br>
>     p *:=* [s wait] newProcess.<br>
>     p resume.<br>
>     Processor yield.<br>
>     { p. p suspend }<br>
> <br>
> answers an Array of process p that is past the wait, and the semaphore, s.<br>
> And<br>
> <br>
>     | s p |<br>
>     s *:=* Semaphore new.<br>
>     p *:=* [s wait] newProcess.<br>
>     p resume.<br>
>     Processor yield.<br>
>     p suspend; resume.<br>
>     Processor yield.<br>
>     p isTerminated<br>
> <br>
> answers true, whereas in both cases the process should remain waiting on<br>
> the semaphore.<br>
> <br>
> ><br>
> > Is this an expected behavior or a bug?<br>
> ><br>
> <br>
> IMO it is a dreadful bug.<br>
> <br>
> > If a bug, should a suspended process somehow remember its previous state<br>
> > and/or queue and return to the same one if resumed?<br>
> ><br>
> <br>
> IMO the primitive should back up the process to the<br>
> wait/primitiveEnterCriticalSection. This is trivial to implement in the<br>
> image, but is potentially non-atomic.  It is perhaps tricky to implement in<br>
> the VM, but will be atomic.<br>
> <br>
> Sorry if I'm missing something :)<br>
> ><br>
> <br>
> You're not missing anything :-)  Here's another example that answers two<br>
> processes which should both block but if resumed both make progress.<br>
> <br>
>     | s p1 p2 m |<br>
>     s *:=* Semaphore new.<br>
>     m *:=* Mutex new.<br>
>     p1 *:=* [m critical: [s wait]] newProcess.<br>
>     p1 resume.<br>
>     p2 *:=* [m critical: [s wait]] newProcess.<br>
>     p2 resume.<br>
>     Processor yield.<br>
>     { p1. p1 suspend. p2. p2 suspend }<br>
> <br>
> p1 enters the mutex's critical section, becoming the mutex's owner. p2 then<br>
> blocks attempting to enter m's critical section.  Let's resume these two,<br>
> and examine the semaphore and mutex:<br>
> <br>
>     | s p1 p2 m |<br>
>     s *:=* Semaphore new.<br>
>     m *:=* Mutex new.<br>
>     p1 *:=* [m critical: [s wait]] newProcess.<br>
>     p1 resume.<br>
>     p2 *:=* [m critical: [s wait]] newProcess.<br>
>     p2 resume.<br>
>     Processor yield.<br>
>     { p1. p1 suspend. p2. p2 suspend }.<br>
>     p1 resume. p2 resume.<br>
>     Processor yield.<br>
>     { s. m. p1. p1 isTerminated. p2. p2 isTerminated }<br>
> <br>
> In this case the end result for p2 is accidentally correct. It ends up<br>
> waiting on s within m's critical section. But p1 ends up terminated.  IMO<br>
> the correct result is that p1 remains waiting on s, and is still the owner<br>
> of m, and p2 remains blocked trying to take ownership of m.<br>
> <br>
<br>
Perfect example! My naive expectation was when a process inside a critical section gets suspended the Mutex gets unlocked but that's apparently wrong :)<br></blockquote><div><br></div><div class="gmail_default" style="font-size:small">suspend merely stops the receiver running, makes it unrunnable.  Here's the StackInterpreter's version of the primitive:</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><b style="color:rgb(0,0,0)">primitiveSuspend</b><font color="#000000"><br>    </font><font color="#008080">"Primitive. Suspend the receiver, aProcess such that it can be executed again<br>    by sending #resume. If the given process is not currently running, take it off<br>    its corresponding list. The primitive returns the list the receiver was previously on."</font><font color="#000000"><br>    </font><font color="#808080">|</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#808080">|</font><font color="#000000"><br>    </font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">stackTop</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">=</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">activeProcess</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">pop:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">thenPush:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#800000">^</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">transferTo:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">wakeHighestPriority</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#008080">"XXXX Fixme. We should really check whether myList is a kind of LinkedList or not<br>    but we can't easily so just do a quick check for nil which is the most common case."</font><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">=</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#800000">^</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">primitiveFailFor:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">PrimErrBadReceiver</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#008080">"Alas in Spur we need a read barrier"</font><font color="#000000"><br>    </font><font color="#000000">(</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">isForwarded:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">)</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">followForwarded:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">storePointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">withValue:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">removeProcess:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fromList:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">successful</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">storePointerUnchecked:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">withValue:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">pop:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">thenPush:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">]</font><br></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">There are two interpretations possible here.  One is that suspend should fail if attempted on a process that is waiting on a condition variable.  Another is that if the process is waiting on a condition variable, then suspend should back up the process so that on resumption the wait is retried.  The first is simple.  The second is horribly complicated (backing up execution is difficult; the process could have been added to the condition variable's list, and must be removed).  I'm interested in which of these people think we should implement.  If just failure, things are easy :-)  Anyway, let's understand the bug.</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">The big issue is with the lines</font></div><div class="gmail_default" style="font-size:small"><font color="#000000">    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#008080">"XXXX Fixme. We should really check whether myList is a kind of LinkedList or not<br>    but we can't easily so just do a quick check for nil which is the most common case."</font><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">=</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#800000">^</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">primitiveFailFor:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">PrimErrBadReceiver</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">This should really check for the process's myList being its run queue, the linked list in the processor scheduler's runnableProcesses array. But it doesn't.  It only checks for nil.  In our case p2 is waiting on m, so its list is m, and not nil. Hence the primitive succeeds. It then continues to remove p2 from m, and set its list to nil:</font></div><font color="#000000"><br>    </font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">removeProcess:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fromList:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">successful</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">storePointerUnchecked:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">withValue:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">pop:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">thenPush:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">]</font></div><div class="gmail_quote"><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><br></span></font></div><div class="gmail_quote"><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><span class="gmail_default" style="font-size:small">So now when p1 is terminated and m releases its critical section there is no p2 waiting on it that m can schedule to take ownership.  Hence p2 does not take ownership of m.</span></span></font></div><div class="gmail_quote"><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><br></span></font></div><div class="gmail_quote"><font color="#000000"><span style="caret-color: rgb(0, 0, 0);"><span class="gmail_default" style="font-size:small">Now, if we're going to fix this, one easy way is for the suspend primitive to insist that a process's myList is its run queue for suspend to succeed.  If primitiveSuspend can rely on the process's priority inst var then the check is easy, something like:</span><br></span></font><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><b style="color:rgb(0,0,0)">primitiveSuspend</b><font color="#000000"><br>    </font><font color="#008080">"Primitive. Suspend the receiver, aProcess such that it can be executed again<br>    by sending #resume. If the given process is not currently running, take it off<br>    its corresponding list. The primitive returns the list the receiver was previously on."</font><font color="#000000"><br>    </font><font color="#808080">|</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myRunQueue</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#808080">|</font><font color="#000000"><br>    </font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">stackTop</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">=</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">activeProcess</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">pop:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">thenPush:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#800000">^</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">transferTo:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">wakeHighestPriority</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">myRunQueue</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><br>                        </font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">(</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchInteger:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">PriorityIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000">)</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">-</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><br>                        </font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">(</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">ProcessListsIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">schedulerPointer</font><font color="#000000">)</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">=</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myRunQueue</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#800000">^</font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">primitiveFailFor:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">PrimErrBadReceiver</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#008080">"Alas in Spur we need a read barrier"</font><font color="#000000"><br>    </font><font color="#000000">(</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">isForwarded:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">)</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">followForwarded:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">storePointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">withValue:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">]</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">removeProcess:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fromList:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">successful</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:</font><font color="#000000"><br>        </font><font color="#000000">[</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">storePointerUnchecked:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">withValue:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">nilObject</font><font color="#000000">.</font><font color="#000000"><br>        <span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">pop:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">thenPush:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myList</font><font color="#000000">]</font><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">We were talking about manipulating priority in another thread. For the above to work we have to keep priority and myList in sync when manipulating the priority of a runnable process.  For me this is not a big issue; manipulating priority directly counts as shooting oneself in the foot. So with that said, the important questions are</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">Should we change primitiveSuspend to the above? i.e. have primitiveSuspend fail unless it is suspending a runnable process.</font></div><div class="gmail_default" style="font-size:small"><font color="#000000">If so, is this optional behaviour? i.e. should the VM maintain a flag, alongside preemptionYields, which if set (as it is by default) obtains the old behaviour, an dif clear ob tains the new (correct) behaviour of failing if waiting on condition variables.</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">So let's look at the alternative; having suspend succeed if the process is waiting on a condition variable, but arranging somehow that the process remains in the wait state.  This is preferrable (because it doesn't introduce a new error into the system), but is apparently more complex. So...</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">The primitive could alternatively succeed, but </font></div><div class="gmail_default" style="font-size:small"><font color="#000000">- not remove process from myList unless myList is its run queue.  i.e. if waiting on a condition variable</font></div><div class="gmail_default" style="font-size:small"><font color="#000000">- have primitiveResume *not* resume a process whose myList is not its runQueue.</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">I think this works.  The requirement is that primitiveResume check the process's myList.  If myList is a runQueue then resume functions as normal.  If myList is not a run queue (presumably a condition variable) then resume does nothing.o  That's simple.</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">So how to determine if a process's myList is a run queue.  One way is to have the VM maintain the class LinkedList.  LinkedList is not in the specialObjectsArray; Semaphore is.  One way is to assume Semaphore always inherits directly from LinkedList (safe assumption) and have the VM derive LinkedList by Semaphore superclass (objectMemory fetchPointer: SuperclassIndex ofObject: (objectMemory splObj: ClassSemaphoreIndex)).  But this is not a particularly strong test.  One might legitimately construct a list of suspended processes on a LinkedList that was not a run queue.  So safest is simply to compare myList against the list at the process's priority:</font></div><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">MyListIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">myRunQueue</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><b style="color:rgb(0,0,0)">:=</b><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">objectMemory</font><font color="#000000"><br>                        </font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">(</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchInteger:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">PriorityIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">process</font><font color="#000000">)</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">-</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">1</font><font color="#000000"><br>                        </font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000000">(</font><font color="#000000">objectMemory</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">fetchPointer:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#404040">ProcessListsIndex</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ofObject:</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#800000">self</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">schedulerPointer</font><font color="#000000">)</font><font color="#000000">.</font><font color="#000000"><br>    </font><font color="#6B6B6B">myList</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">=</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#6B6B6B">myRunQueue</font><font color="#000000"><span class="gmail-Apple-converted-space"> </span></font><font color="#000080">ifTrue:<span class="gmail_default" style="font-size:small">...</span><span class="gmail_default" style="font-size:small"></span><span class="gmail_default" style="font-size:small"></span></font><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">I expect this adds negligible overhead to suspend and resume.</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><div class="gmail_default" style="font-size:small"><font color="#000000">So, sorry about the level of detail, but could people carefully review these two proposals?</font></div><div class="gmail_default" style="font-size:small"><font color="#000000"><br></font></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
But still, there's something wrong with the example: If p1 resumes it releases m's ownership and terminates, then p2 takes over and proceeds inside the critical section and gets blocked at the semaphore. I'd expect p2 would become the owner of the Mutex m BUT it's not! There's no owner while p2 is sitting at the semaphore. Try:<br>
<br>
    | s p1 p2 m |<br>
    s := Semaphore new.<br>
    m := Mutex new.<br>
    p1 := [m critical: [s wait]] newProcess.<br>
    p1 resume.<br>
    p2 := [m critical: [s wait]] newProcess.<br>
    p2 resume.<br>
    Processor yield.<br>
    { p1. p1 suspend. p2. p2 suspend }.<br>
    p1 resume. p2 resume.<br>
    Processor yield.<br>
    { s. m. p1. p1 isTerminated. p2. p2 isTerminated. m isOwned. m instVarNamed: 'owner' }<br>
<br>
It seems to me that when p2 gets suspended it is stopped somewhere inside #primitiveEnterCriticalSection before the owner is set and when it gets resumed it is placed into the runnable queue with the pc pointing right behind the primitive and so when it runs it just continues inside #critical and get blocked at the semaphore, all without having the ownership.<br>
<br>
Is this interpretation right? It would mean Mutex's critical section can be entered twice via this mechanism...<br>
<br>
Cuis does set the ownership to p2 in this example.<br>
<br>
Thanks again,<br>
<br>
Jaromir<br>
> <br>
> ><br>
> > Best,<br>
> > ~~~<br>
> > ^[^    Jaromir<br>
> ><br>
> > Sent from Squeak Inbox Talk<br>
> ><br>
> <br>
> _,,,^..^,,,_<br>
> best, Eliot<br>
> -------------- next part --------------<br>
> An HTML attachment was scrubbed...<br>
> URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211227/8719df13/attachment.html" rel="noreferrer" target="_blank">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211227/8719df13/attachment.html</a>><br>
> <br>
> <br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div>