<div dir="ltr">Hi Chris,<div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 2, 2018 at 4:03 PM, Chris Muller <span dir="ltr"><<a href="mailto:asqueaker@gmail.com" target="_blank">asqueaker@gmail.com</a>></span> wrote:<br><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 guys,<br>
<br>
Thanks, Eliot, and please accept my apologies -- when I later rebooted<br>
the image it still only had 1182, and so I'm not 100% certain I had<br>
updated that image or simply hadn't saved after I updated.</blockquote><div><br></div><div>If you look at the changes file you should be able to see whether the changes from 1183, 1184 et al are present on the changes file or not.</div><div>The package name is logged on the changes file as a comment doit, e.g. </div><div>"Kernel"!</div><div><br></div><div>If people think it's a good idea we could also log update beginnings and endings.  It would be nice to see</div><div>"==========  Update completed:  18150 -> 18163 =========="!</div><div>logged on the changes file.</div><div> </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">  I am going<br>
to update and save everything and keep moving forward normally to see<br>
it happens again.  The 201807260206 was flawless for me in the first<br>
big stress test, this time I'll be sure to save my updated trunk from<br>
the get go.<br></blockquote><div><br></div><div>Cool.  Thanks.  And if there is a lock up, I'd love to look at the image with you.</div><div> </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>
Thanks for that reminder about kill SIGUSR1, Levente.  I don't use<br>
post-it notes but that's so useful I probably should get one for<br>
that..   :)<br>
<br>
Best,<br>
  Chris<br>
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
On Thu, Aug 2, 2018 at 6:52 AM, Levente Uzonyi <<a href="mailto:leves@caesar.elte.hu">leves@caesar.elte.hu</a>> wrote:<br>
> Hi Chris,<br>
><br>
> Did you try to send SIGUSR1 to this image before killing it? (assuming it<br>
> didn't happen on Windows)<br>
><br>
> Levente<br>
><br>
><br>
> On Wed, 1 Aug 2018, Chris Muller wrote:<br>
><br>
>> My image just locked after it tried to unwind normally from a network<br>
>> timeout.   I had to kill it from the OS.<br>
>><br>
>> Eliot would you guide me how to get my trunk image rolled back to a<br>
>> state without this fix so I can try to get back to where I was to see<br>
>> if its related?<br>
>><br>
>> Should I just load Kernel-eem.1184, an earlier one,<br>
>> or something else?<br>
>><br>
>><br>
>><br>
>> On Fri, Jul 27, 2018 at 1:08 PM,  <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> wrote:<br>
>>><br>
>>> A new version of Kernel was added to project The Inbox:<br>
>>> <a href="http://source.squeak.org/inbox/Kernel-eem.1185.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/<wbr>inbox/Kernel-eem.1185.mcz</a><br>
>>><br>
>>> ==================== Summary ====================<br>
>>><br>
>>> Name: Kernel-eem.1185<br>
>>> Author: eem<br>
>>> Time: 27 July 2018, 11:08:12.641836 am<br>
>>> UUID: 7296ad00-708d-4cef-b6bc-<wbr>ceb24d897a70<br>
>>> Ancestors: Kernel-eem.1184<br>
>>><br>
>>> In releaseCriticalSection: use isUnwindContext instead of the more<br>
>>> fragile context selector == #ensure:.  Now it will handle ifCurtailed: too.<br>
>>> Thanks Tobias!<br>
>>><br>
>>> Reformat Process>>#terminate.  It was baaad.<br>
>>><br>
>>> =============== Diff against Kernel-eem.1184 ===============<br>
>>><br>
>>> Item was changed:<br>
>>>   ----- Method: Process>><wbr>releaseCriticalSection: (in category 'private')<br>
>>> -----<br>
>>>   releaseCriticalSection: runnable<br>
>>>         "Figure out if we are terminating a process that is in the<br>
>>> ensure: block of a critical section.<br>
>>>          In this case, if the block has made progress, pop the<br>
>>> suspendedContext so that we leave the<br>
>>>          ensure: block inside the critical: without signaling the<br>
>>> semaphore/exiting the primitive section,<br>
>>>          since presumably this has already happened.  But if it hasn't<br>
>>> made progress but is beyond the<br>
>>> +        wait (which we can tell by the oldList being one of the runnable<br>
>>> lists, i.e. a LinkedList, not a<br>
>>> -        wait (which we can tell my the oldList being one of the runnable<br>
>>> lists, i.e. a LinkedList, not a<br>
>>>          Semaphore or Mutex, et al), then the ensure: block needs to be<br>
>>> run."<br>
>>>         | selectorJustSent |<br>
>>>         (suspendedContext method pragmaAt: #criticalSection) ifNil:<br>
>>> [^self].<br>
>>>         selectorJustSent := suspendedContext selectorJustSentOrSelf.<br>
>>><br>
>>>         "Receiver and/or argument blocks of ensure: in<br>
>>> Semaphore>>critical: or Mutex>>#critical:"<br>
>>>         suspendedContext isClosureContext ifTrue:<br>
>>> +               [suspendedContext sender isUnwindContext ifTrue:<br>
>>> -               [suspendedContext sender selector == #ensure: ifTrue:<br>
>>>                         [| notWaitingButMadeNoProgress |<br>
>>>                         "Avoid running the ensure: block twice, popping<br>
>>> it if it has already been run. If runnable<br>
>>>                          but at the wait, leave it in place. N.B. No need<br>
>>> to check if the block receiver of ensure: has<br>
>>>                          not started to run (via suspendedContext pc =<br>
>>> suspendedContext startpc) because ensure:<br>
>>>                          uses valueNoContextSwitch, and so there is no<br>
>>> suspension point before the wait."<br>
>>>                          notWaitingButMadeNoProgress :=<br>
>>>                                 runnable<br>
>>>                                 and: [selectorJustSent == #wait<br>
>>>                                 and: [suspendedContext sender<br>
>>> selectorJustSentOrSelf == #valueNoContextSwitch]].<br>
>>>                          notWaitingButMadeNoProgress ifFalse:<br>
>>>                                 [suspendedContext := suspendedContext<br>
>>> home]].<br>
>>>                  ^self].<br>
>>><br>
>>>         "Either Semaphore>>critical: or Mutex>>#critical:.  Is the<br>
>>> process still blocked?  If so, nothing further to do."<br>
>>>         runnable ifFalse: [^self].<br>
>>><br>
>>>         "If still at the wait the ensure: block has not been activated,<br>
>>> so signal to restore."<br>
>>>         selectorJustSent == #wait ifTrue:<br>
>>>                 [suspendedContext receiver signal].<br>
>>><br>
>>>         "If still at the lock primitive and the lock primitive just<br>
>>> acquired ownership (indicated by it answering false)<br>
>>>          then the ensure block has not been activated, so explicitly<br>
>>> primitiveExitCriticalSection to unlock."<br>
>>>         (selectorJustSent == #primitiveEnterCriticalSection<br>
>>>          or: [selectorJustSent ==<br>
>>> #<wbr>primitiveTestAndSetOwnershipOf<wbr>CriticalSection]) ifTrue:<br>
>>>                 [(suspendedContext stackPtr > 0<br>
>>>                   and: [suspendedContext top == false]) ifTrue:<br>
>>>                         [suspendedContext receiver<br>
>>> primitiveExitCriticalSection]]<wbr>!<br>
>>><br>
>>> Item was changed:<br>
>>>   ----- Method: Process>>terminate (in category 'changing process state')<br>
>>> -----<br>
>>>   terminate<br>
>>>         "Stop the process that the receiver represents forever.<br>
>>>          Unwind to execute pending ensure:/ifCurtailed: blocks before<br>
>>> terminating.<br>
>>>          If the process is in the middle of a critical: critical section,<br>
>>> release it properly."<br>
>>><br>
>>>         | ctxt unwindBlock oldList |<br>
>>> +       self isActiveProcess ifTrue:<br>
>>> +               [ctxt := thisContext.<br>
>>> +                [ctxt := ctxt findNextUnwindContextUpTo: nil.<br>
>>> +                 ctxt ~~ nil] whileTrue:<br>
>>> +                       [(ctxt tempAt: 2) ifNil:<br>
>>> +                               ["N.B. Unlike Context>>unwindTo: we do<br>
>>> not set complete (tempAt: 2) to true."<br>
>>> +                                unwindBlock := ctxt tempAt: 1.<br>
>>> +                                thisContext terminateTo: ctxt.<br>
>>> +                                unwindBlock value]].<br>
>>> -       self isActiveProcess ifTrue: [<br>
>>> -               ctxt := thisContext.<br>
>>> -               [       ctxt := ctxt findNextUnwindContextUpTo: nil.<br>
>>> -                       ctxt isNil<br>
>>> -               ] whileFalse: [<br>
>>> -                       (ctxt tempAt: 2) ifNil:[<br>
>>> -                               ctxt tempAt: 2 put: nil.<br>
>>> -                               unwindBlock := ctxt tempAt: 1.<br>
>>> -                               thisContext terminateTo: ctxt.<br>
>>> -                               unwindBlock value].<br>
>>> -               ].<br>
>>>                 thisContext terminateTo: nil.<br>
>>>                 self suspend.<br>
>>> +               "If the process is resumed this will provoke a<br>
>>> cannotReturn: error.<br>
>>> +                Would self debug: thisContext title: 'Resuming a<br>
>>> terminated process' be better?"<br>
>>> +               ^self].<br>
>>> -       ] ifFalse:[<br>
>>> -               "Always suspend the process first so it doesn't<br>
>>> accidentally get woken up.<br>
>>> -                N.B. If oldList is a LinkedList then the process is<br>
>>> runnable. If it is a Semaphore/Mutex et al<br>
>>> -                then the process is blocked, and if it is nil then the<br>
>>> process is already suspended."<br>
>>> -               oldList := self suspend.<br>
>>> -               suspendedContext ifNotNil:<br>
>>> -                       ["Release any method marked with the<br>
>>> <criticalSection> pragma.<br>
>>> -                         The argument is whether the process is<br>
>>> runnable."<br>
>>> -                        self releaseCriticalSection: (oldList isNil or:<br>
>>> [oldList class == LinkedList]).<br>
>>><br>
>>> +       "Always suspend the process first so it doesn't accidentally get<br>
>>> woken up.<br>
>>> +        N.B. If oldList is a LinkedList then the process is runnable. If<br>
>>> it is a Semaphore/Mutex et al<br>
>>> +        then the process is blocked, and if it is nil then the process<br>
>>> is already suspended."<br>
>>> +       oldList := self suspend.<br>
>>> +       suspendedContext ifNotNil:<br>
>>> +               ["Release any method marked with the <criticalSection><br>
>>> pragma.<br>
>>> +                 The argument is whether the process is runnable."<br>
>>> +                self releaseCriticalSection: (oldList isNil or: [oldList<br>
>>> class == LinkedList]).<br>
>>> -                       "If terminating a process halfways through an<br>
>>> unwind, try to complete that unwind block first."<br>
>>> -                       (suspendedContext findNextUnwindContextUpTo: nil)<br>
>>> ifNotNil:<br>
>>> -                               [:outer|<br>
>>> -                               (suspendedContext<br>
>>> findContextSuchThat:[:c| c closure == (outer tempAt: 1)]) ifNotNil:<br>
>>> -                                       [:inner| "This is an unwind block<br>
>>> currently under evaluation"<br>
>>> -                                       suspendedContext<br>
>>> runUntilErrorOrReturnFrom: inner]].<br>
>>><br>
>>> +               "If terminating a process halfways through an unwind, try<br>
>>> to complete that unwind block first."<br>
>>> +               (suspendedContext findNextUnwindContextUpTo: nil)<br>
>>> ifNotNil:<br>
>>> +                       [:outer|<br>
>>> +                        (suspendedContext findContextSuchThat:[:c| c<br>
>>> closure == (outer tempAt: 1)]) ifNotNil:<br>
>>> +                               [:inner| "This is an unwind block<br>
>>> currently under evaluation"<br>
>>> +                                suspendedContext<br>
>>> runUntilErrorOrReturnFrom: inner]].<br>
>>> +<br>
>>> +               ctxt := self popTo: suspendedContext bottomContext.<br>
>>> +               ctxt == suspendedContext bottomContext ifFalse:<br>
>>> +                       [self debug: ctxt title: 'Unwind error during<br>
>>> termination'].<br>
>>> +               "Set the context to its endPC for the benefit of<br>
>>> isTerminated."<br>
>>> +               ctxt pc: ctxt endPC]!<br>
>>> -                       ctxt := self popTo: suspendedContext<br>
>>> bottomContext.<br>
>>> -                       ctxt == suspendedContext bottomContext ifFalse:<br>
>>> -                               [self debug: ctxt title: 'Unwind error<br>
>>> during termination'].<br>
>>> -                       "Set the context to its endPC for the benefit of<br>
>>> isTerminated."<br>
>>> -                       ctxt pc: ctxt endPC]]!<br>
>>><br>
>>><br>
><br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div 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></div>