<div dir="ltr">Hi Ben,<div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 25, 2014 at 7:56 AM, Ben Coman <span dir="ltr">&lt;<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><u></u>


  

<div bgcolor="#ffffff" text="#000000">
Over the last few days I have been looking deeper into the image
locking when suspending a process. It is an
interesting rabbit hole [1] that leads to pondering the Delay
machinery, that leads to some VM questions. <br>
<br>
When  pressing the interrupt key it seems to always opens
the debugger with the following call stack. <br>
Semaphore&gt;&gt;critical:   &#39;self wait&#39;<br>
BlockClosure&gt;&gt;ensure:     &#39;self valueNoContextSwitch&#39;<br>
Semaphore&gt;&gt;critical:      &#39;ensure: [ caught ifTrue: [self signal]]<br>
Delay&gt;&gt;schedule         &#39;AccessProtect critical: [&#39;<br>
Delay&gt;&gt;wait              &#39;self schedule&#39;<br>
WorldState&gt;&gt;interCyclePause:<br>
<br>
I notice...<br>
    Delay class &gt;&gt; initialize <br>
        TimingSemaphore := (Smalltalk specialObjectsArray at: 30).<br>
and...<br>
    Delay class &gt;&gt; startTimerEventLoop<br>
        TimingSemaphore := Semaphore new.<br>
which seems incongruous that TimingSemaphore is set in differently.  So
while I presume this critical stuff all works fine, just in an exotic
way,  my entropy-guarding-neuron would just like confirm this is so.<br></div></blockquote><div><br></div><div>The TimingSemaphore gets installed in the specialObjectsArray via</div><div><br></div><div>primSignal: aSemaphore atMilliseconds: aSmallInteger</div>
<div><span class="" style="white-space:pre">        </span>&quot;Signal the semaphore when the millisecond clock reaches the value of the second argument. Fail if the first argument is neither a Semaphore nor nil. Essential. See Object documentation whatIsAPrimitive.&quot;</div>
<div><span class="" style="white-space:pre">        </span>&lt;primitive: 136&gt;</div><div><span class="" style="white-space:pre">        </span>^self primitiveFailed</div><div> </div><div>and from that the VM sets the nextWakeupUsecs:</div>
<div><br></div><div><div>primitiveSignalAtMilliseconds</div><div><span class="" style="white-space:pre">        </span>&quot;Cause the time semaphore, if one has been registered, to be</div><div><span class="" style="white-space:pre">        </span> signalled when the microsecond clock is greater than or equal to</div>
<div><span class="" style="white-space:pre">        </span> the given tick value. A tick value of zero turns off timer interrupts.&quot;</div><div><span class="" style="white-space:pre">        </span>| msecsObj msecs deltaMsecs sema |</div>
<div><span class="" style="white-space:pre">        </span>&lt;var: #msecs type: #usqInt&gt;</div><div><span class="" style="white-space:pre">        </span>msecsObj := self stackTop.</div><div><span class="" style="white-space:pre">        </span>sema := self stackValue: 1.</div>
<div><span class="" style="white-space:pre">        </span>msecs := self positive32BitValueOf: msecsObj.</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>self successful ifTrue:</div>
<div><span class="" style="white-space:pre">                </span>[(objectMemory isSemaphoreOop: sema) ifTrue:</div><div><span class="" style="white-space:pre">                        </span>[<b>objectMemory splObj: TheTimerSemaphore put: sema</b>.</div><div>
<span class="" style="white-space:pre">                        </span> deltaMsecs := msecs - (self ioMSecs bitAnd: MillisecondClockMask).</div><div><span class="" style="white-space:pre">                        </span> deltaMsecs &lt; 0 ifTrue:</div><div><span class="" style="white-space:pre">                                </span>[deltaMsecs := deltaMsecs + MillisecondClockMask + 1].</div>
<div><span class="" style="white-space:pre">                        </span> <b>nextWakeupUsecs := self ioUTCMicroseconds + (deltaMsecs * 1000)</b>.</div><div><span class="" style="white-space:pre">                        </span> ^self pop: 2].</div><div><span class="" style="white-space:pre">                </span> sema = objectMemory nilObject ifTrue:</div>
<div><span class="" style="white-space:pre">                        </span>[objectMemory</div><div><span class="" style="white-space:pre">                                </span>storePointer: TheTimerSemaphore</div><div><span class="" style="white-space:pre">                                </span>ofObject: objectMemory specialObjectsOop</div>
<div><span class="" style="white-space:pre">                                </span>withValue: objectMemory nilObject.</div><div><span class="" style="white-space:pre">                        </span> <b>nextWakeupUsecs := 0</b>.</div><div><span class="" style="white-space:pre">                        </span> ^self pop: 2]].</div>
<div><span class="" style="white-space:pre">        </span>self primitiveFailFor: PrimErrBadArgument</div></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div bgcolor="#ffffff" text="#000000">
<br>
--------------<br>
<br>
In Delay class &gt;&gt; handleTimerEvent the comment says... <br>
    &quot;Handle a timer event....   <br>
          -a timer signal (not explicitly specified)&quot;<br>
...is that event perhaps a &#39;tick&#39; generated periodically by the VM via
that item from specialObjectArray ?  Or is there some other mechanism ?<br></div></blockquote><div><br></div><div>Every time the VM checks for interrupts, which, in the Cog.Stack VMs is controlled by the heartbeat frequency, which defaults to 2 milliseconds, the VM checks if the current time has progressed to or beyond nextWakeupUsecs and signals the timer semaphore if so.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div bgcolor="#ffffff" text="#000000">--------------<br>

<br>
[1] <a href="http://www.urbandictionary.com/define.php?term=Rabbit+Hole" target="_blank">http://www.urbandictionary.com/define.php?term=Rabbit+Hole</a></div></blockquote><div><br></div><div>and the problem here is not in the VM.  So climb out and breath some fresh air ;-)</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div bgcolor="#ffffff" text="#000000">cheers -ben<br>

<br>
<br>
P.S. I&#39;ve left the following for some initial context as I change the
subject.  btw Nicolai, I confirm that my proposed fixes only work on
Windows, not Mavericks (and I haven&#39;t checked Linux).<br>
<br>
Nicolai Hess wrote:
<blockquote type="cite">
  <div dir="ltr"><br>
  <div class="gmail_extra">Hi ben, thank you for looking at this.<br>
  </div>
  <div class="gmail_extra"><br>
  <div class="gmail_quote">2014-07-22 20:17 GMT+02:00 <span dir="ltr">&lt;<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>&gt;</span>:<br>
  <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
    <div bgcolor="#ffffff" text="#000000">
I thought this might be interesting to learn, so I&#39;ve gave it a go.  I 
had some success at the end, but I&#39;ll give a progressive report.<br>
    <br>
First I thought I&#39;d try moving the update of StringMorph outside the
worker-process using a Morph&#39;s #step method as follows...<br>
    <br>
Morph subclass: #BackgroundWorkDisplayMorph<br>
    instanceVariableNames: &#39;interProcessString stringMorph&#39;<br>
    classVariableNames: &#39;&#39;<br>
    category: &#39;BenPlay&#39;<br>
    &quot;---------&quot;<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;initializeMorph<br>
    self color: Color red.    <br>
    stringMorph := StringMorph new.<br>
    self addMorphBack: stringMorph.<br>
    self extent:(300@50).<br>
    &quot;---------&quot;<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;newWorkerProcess<br>
    ^[     <br>
        | work | <br>
        work := 0.<br>
        [     20 milliSeconds asDelay wait. <br>
            work := work + 1.<br>
            interProcessString := work asString.<br>
        ] repeat.<br>
    ] newProcess.<br>
    &quot;---------&quot;<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;step<br>
    stringMorph contents: interProcessString.<br>
    &quot;---------&quot;<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;stepTime<br>
    ^50<br>
    &quot;---------&quot;<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;initialize<br>
    | workerProcess running |<br>
    super initialize.<br>
    self initializeMorph.<br>
    <br>
    workerProcess := self newWorkerProcess.<br>
    running := false.<br>
                                                              <br>
    self on: #mouseUp send: #value to: <br>
    [      (running := running not)<br>
            ifTrue: [  workerProcess resume. self color: Color green.  ]<br>
            ifFalse: [ workerProcess suspend. self color: Color red. ]<br>
    ]<br>
    &quot;---------&quot;<br>
    <br>
   <br>
    <br>
But evaluating &quot;BackgroundWorkDisplayMorph new openInWorld&quot;  found this
exhibited the same problematic behavior you reported... Clicking on the
morph worked a few times and then froze the UI until Cmd-. pressed a
few times.<br>
    </div>
  </blockquote>
  <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
    <div bgcolor="#ffffff" text="#000000"><br>
However I found the following never locked the GUI.<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;initialize<br>
    &quot;BackgroundWorkDisplayMorph new openInWorld&quot;<br>
    | workerProcess running |<br>
    super initialize.<br>
    self initializeMorph.<br>
    <br>
    workerProcess := self newWorkerProcess.<br>
    running := false.<br>
                                                                <br>
    [ [      (running := running not)<br>
            ifTrue: [  workerProcess resume. self color: Color green  ]<br>
            ifFalse: [ workerProcess suspend. self color: Color red ].<br>
        10 milliSeconds asDelay wait.    <br>
    ] repeat ] fork.<br>
    &quot;---------&quot;<br>
    <br>
    </div>
  </blockquote>
  <div><br>
  </div>
  <div>This locks the UI as well. Not every timet hough. I did this 5
times, every time in a freshly loaded image and it happens two times.<br>
  </div>
  <div><br>
 </div>
  <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
    <div bgcolor="#ffffff" text="#000000">So the problem seemed to not
be with #suspend/#resume or with the
shared variable /interProcessString/.  Indeed, since in the worker
thread /interProcessString/ is atomically assigned a copy via
#asString, and the String never updated, I think there is no need to
surround use of it with a critical section. <br>
    <br>
The solution then was to move the &quot;#resume/#suspend&quot; away from the
&quot;#on: #mouseUp send: #value to:&quot; as follows...<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;initialize<br>
    &quot;BackgroundWorkDisplayMorph new openInWorld&quot;<br>
    | workerProcess running lastRunning |<br>
    super initialize.<br>
    self initializeMorph.<br>
    <br>
    workerProcess := self newWorkerProcess.<br>
    lastRunning := running := false.<br>
                                                                <br>
    [ [    lastRunning = running ifFalse: <br>
        [    running<br>
                ifTrue: [  workerProcess resume  ]<br>
                ifFalse: [ workerProcess suspend ].     <br>
            lastRunning := running.<br>
        ].                 <br>
        10 milliSeconds asDelay wait.<br>
    ] repeat ] fork.    <br>
    <br>
    self on: #mouseUp send: #value to: <br>
    [      (running := running not)<br>
            ifTrue: [  self color: Color green.  ]<br>
            ifFalse: [ self color: Color red. ]<br>
    ]<br>
    &quot;---------&quot;<br>
    </div>
  </blockquote>
  <div><br>
  </div>
  <div>And this too :(<br>
  </div>
  <div><br>
 </div>
  <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
    <div bgcolor="#ffffff" text="#000000"><br>
And finally remove the busy loop.<br>
    <br>
BackgroundWorkDisplayMorph&gt;&gt;initialize<br>
    &quot;BackgroundWorkDisplayMorph new openInWorld&quot;<br>
    | workerProcess running lastRunning semaphore |<br>
    super initialize.<br>
    self initializeMorph.<br>
    <br>
    workerProcess := self newWorkerProcess.<br>
    lastRunning := running := false.<br>
    semaphore := Semaphore new.<br>
                                                                <br>
    [ [    semaphore wait.<br>
        running<br>
            ifTrue: [  workerProcess resume  ]<br>
            ifFalse: [ workerProcess suspend ].              <br>
    ] repeat ] fork.    <br>
    <br>
    self on: #mouseUp send: #value to: <br>
    [      (running := running not)<br>
            ifTrue: [  self color: Color green.  ]<br>
            ifFalse: [ self color: Color red. ].<br>
        semaphore signal.<br>
    ]<br>
    &quot;---------&quot;<br>
    <br>
    </div>
  </blockquote>
  <div><br>
  </div>
  <div><br>
  </div>
  <div>And this locks the UI too. (Loaded the code 20 times, every time
after a fresh image start up. Two times I got a locked <br>
  </div>
  <div>ui after the first two clicks).<br>
  </div>
  <div>And I don&#39;t understand this code :)<br>
  <br>
 <br>
  </div>
  <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
    <div bgcolor="#ffffff" text="#000000">Now I can&#39;t say how close
that is to how it &quot;should&quot; be done.  Its the
first time I used sempahores and just what I discovered hacking around.
  But hey! it works :)<br>
    <br>
cheers -ben
    <div>
    <div><br>
    <br>
    <br>
Nicolai Hess wrote:
    <blockquote type="cite">
      <div dir="ltr">
      <div><span><span style="background-color:rgb(255,255,255)" title="kämpfe immernoch damit">I am still struggling with it. <br>
      <br>
      </span></span></div>
      <span><span style="background-color:rgb(255,255,255)" title="kämpfe immernoch damit">Any ideas?<br>
      </span></span></div>
      <div class="gmail_extra"><br>
      <br>
      <div class="gmail_quote">2014-07-09 11:19 GMT+02:00 Nicolai Hess <span dir="ltr">&lt;<a href="mailto:nicolaihess@web.de" target="_blank">nicolaihess@web.de</a>&gt;</span>:<br>
      <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
        <div dir="ltr"><br>
        <div class="gmail_extra"><br>
        <br>
        <div class="gmail_quote">2014-07-09 2:07 GMT+02:00 Eliot
Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span>:
        <div><br>
        <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
          <div dir="ltr">Hi Nicolai,
          <div class="gmail_extra"><br>
          <br>
          <div class="gmail_quote">
          <div>
          <div>On Tue, Jul 8, 2014 at 7:19 AM, Nicolai Hess <span dir="ltr">&lt;<a href="mailto:nicolaihess@web.de" target="_blank">nicolaihess@web.de</a>&gt;</span>
wrote:<br>
          <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
            <div dir="ltr">
            <div>I want to create a process doing some work and call
#changed on a Morph.<br>
I want to start/suspend/resume or stop this process.<br>
But sometimes, suspending the process locks the UI-Process, <br>
and I don&#39;t know why. Did I miss something or do I have to care when to
call suspend?<br>
            </div>
            <div><br>
            </div>
            <div>Wrapping the &quot;morph changed&quot; call in<br>
            </div>
            <div>UIManager default defer:[ morph changed].<br>
            </div>
            <div>Does not change anything.<br>
            </div>
            <div><br>
Here is an example to reproduce it. <br>
Create the process,<br>
call resume, call supsend. It works, most of the time, <br>
but sometimes, calling suspend locks the ui.<br>
            <br>
p:=[[true] whileTrue:[ Transcript crShow: (DateAndTime now asString).
30 milliSeconds asDelay wait]] newProcess. </div>
            </div>
          </blockquote>
          <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
            <div dir="ltr">
            <div>p resume.<br>
p suspend.<br>
            </div>
            </div>
          </blockquote>
          <div><br>
          </div>
          </div>
          </div>
          <div>If you simply suspend this process at random form a
user-priority process you&#39;ll never be able to damage the Delay
machinery you&#39;re using, but chances are you&#39;ll suspend the process
inside the critical section that Transcript uses to make itself
thread-safe, and that&#39;ll lock up the Transcript. </div>
          </div>
          </div>
          </div>
        </blockquote>
        <div><br>
        </div>
        </div>
        <div>Thank you Eliot<br>
        </div>
        <div>yes I guessed it locks up the critical section, but I
hoped
with would not happen if I the use UIManager defer call.<br>
        </div>
        <div>
        <div><br>
 </div>
        <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
          <div dir="ltr">
          <div class="gmail_extra">
          <div class="gmail_quote">
          <div><br>
          </div>
          <div>ThreadSafeTranscript&gt;&gt;nextPutAll: value</div>
          <div><span> </span></div>
          <div><span> </span>accessSemaphore</div>
          <div><span> </span>critical: [stream nextPutAll: value].</div>
          <div><span> </span>^value</div>
          <div><br>
          </div>
          <div>So instead you need to use a semaphore.  e.g.</div>
          <div><br>
          </div>
          <div>| p s wait |</div>
          <div>s := Semaphore new.</div>
          <div>p:=[[true] whileTrue:[wait ifTrue: [s wait]. Transcript
crShow: (DateAndTime now asString). 30 milliSeconds asDelay wait]]
newProcess.</div>
          <div>wait := true.</div>
          <div>30 milliSeconds asDelay wait.<br>
          </div>
          <div>wait := false.</div>
          <div>s signal</div>
          <div><br>
          </div>
          <div>etc...</div>
          </div>
          </div>
          </div>
        </blockquote>
        <div><br>
        </div>
        </div>
        <div>Is this a common pattern I can find in pharos classes. Or
I
need some help understanding this. The semaphore<br>
        </div>
        <div>wait/signal is used instead of process resume/suspend?<br>
        </div>
        <div><br>
What I want is a process doing repeatly some computation, <br>
calls or triggers an update on a morph, and I want to suspend and
resume this process.<br>
        <br>
I would stop this discussion if someone tells me, &quot;No your are doing it
wrong, go this way ..&quot;,  BUT what strikes me:<br>
in this example, that reproduces my problem more closely:<br>
        <br>
|p m s running|<br>
running:=false.<br>
m:=Morph new color:Color red.<br>
s:= StringMorph new.<br>
m addMorphBack:s.<br>
p:=[[true]whileTrue:[20 milliSeconds asDelay wait. s
contents:(DateAndTime now asString). m changed]] newProcess.<br>
m on:#mouseUp send:#value to:[<br>
    running ifTrue:[p suspend. m color:Color red.]<br>
    ifFalse:[p resume.m color:Color green.].<br>
    running := running not].<br>
m extent:(300@50).<br>
m openInWorld<br>
        <br>
        <br>
        </div>
        <div>clicking on the morph will stop or resume the process, if
it
locks up I can still press alt+dot -&gt;<br>
        </div>
        <div>- a Debugger opens but the UI is still not responsive. I
can
click with the mouse on the debuggers close icon.<br>
        </div>
        <div>- nothing happens, as the UI is still blocked.<br>
        </div>
        <div>- pressing alt+Dot again, the mouse click on the close
icon is
processed and the first debugger window closes<br>
- maybe other debuggers open.<br>
        <br>
Repeating this steps, at some time the system is *fully* responsive
again!<br>
        </div>
        <div>And miraculously, it works after that w<span lang="en"><span>ithout
further</span> <span>blockages.</span></span></div>
        <div>What&#39;s happening here?<span><font color="#888888"><br>
        </font></span></div>
        <span><font color="#888888">
        <div><br>
        </div>
        <div>Nicolai<br>
        </div>
        </font></span>
        <div>
        <div><br></div><blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">
<div class="gmail_quote">
          <div>HTH</div>
          <div><br>
          </div>
          <blockquote class="gmail_quote" style="border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
            <div dir="ltr">
            <div>regards<br>
            </div>
            <span><font color="#888888">Nicolai<span><font color="#888888"><br>
            </font></span></font></span></div>
            <span></span></blockquote>
          </div>
          <span><font color="#888888"><div><br>
          </div>
-- <br>
best,
          <div>Eliot</div></font></span></div></div></blockquote></div></div></div></div></blockquote></div></div></blockquote></div></div></div></blockquote></div></div></div></blockquote></div></blockquote></div>-- <br>
Aloha,<div>Eliot</div>
</div></div>