<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi All,</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I'd like to present to you a rewrite of #terminate and #isTerminated that fixes a few bugs and inconsistencies in process termination. I hoped it might interest you.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I'm a Smalltalk enthusiast with education background in math/CS. I've been experimenting with processes in Squeak lately and discovered a few bugs (or at least inconsistencies) in process termination and would like to offer and discuss
 a solution for Cuis.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The bugs are not unique to Cuis; Squeak/Pharo inherited them too and to a degree even Visual Works and VA are affected. The proposal presented here doesn't copy any VW or VA solution but rather implements a different approach :)</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Before boring you to death I'll list the bugs:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">1. #isTerminated falsely reports almost any bottom context as terminated</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">2. an active process termination bug causes an image freeze </p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">3. a <i>nested</i> unwind bug: ensure blocks may get skipped during unwind</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">4. a failure to complete <i>nested</i> unwind blocks halfway thru execution
</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">5. a failure to correctly execute a non-local return or an error in an unwind block
</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">6. inconsistent semantics of protected blocks unwind during active vs. suspended process termination</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The current implementation of #terminate uses three different approaches to terminate a process:</p>
<p class="MsoNormal">- the active process is terminated via a 'standard' unwind algorithm used in context #unwindTo: or #resume:,</p>
<p class="MsoNormal">- a suspended process termination attempts completing unwind blocks halfway through their execution first using #runUntilErrorOrReturnFrom:</p>
<p class="MsoNormal">- and after that the termination continues unwinding the remaining unwind blocks using the simulation algorithm of #popTo:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This approach <i>looks</i> inconsistent and indeed leads to inconsistencies, undesirable behavior and an instability mentioned above.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The Idea: In my view the easiest and most consistent solution is to simply extend the existing mechanism for completing halfway-through unwind blocks and let it deal with
<b>all</b> unwind blocks. To make this approach applicable to terminating the active process, we suspend it first and then terminate it as a suspended process.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">A commented code is enclosed. </p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I know it's pretty difficult to get a feedback on an ancient code; I'll be all the more grateful for your inputs.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Best regards,</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Jaromir</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">PS:</p>
<p class="MsoNormal">Note the change in newProcess - `Processor activeProcess terminate` is replaced by `Processor activeProcess suspend` because there's no need for `terminate` at the bottom context ("terminate = unwind + suspend") and because it would lead
 to an infinite loop combined with my proposed changes to #terminate.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">PPS:</p>
<p class="MsoNormal">More on the bugs:</p>
<p class="MsoNormal">ad 1) The #isTerminated condition `suspendedContext pc > suspendedContext startpc` is always met after executing the first instruction of the bottom context – generally not a sign of a terminated process.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">ad 2) Explained in [1]. Concerns e.g. examples like </p>
<p class="MsoNormal">              [ [ Processor activeProcess terminate ] ensure: [ Processor activeProcess terminate ] ] fork.
</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">ad 3-4) Explained in detail in [2].</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">One example to illustrate the bug:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">| p |</p>
<p class="MsoNormal">p := [</p>
<p class="MsoNormal">              [</p>
<p class="MsoNormal">                           [ ] ensure: [</p>
<p class="MsoNormal">                                         [ ] ensure: [</p>
<p class="MsoNormal">                                                       Processor activeProcess suspend.
</p>
<p class="MsoNormal">                                                       Transcript show: 'x1'].
</p>
<p class="MsoNormal">                                         Transcript show: 'x2']</p>
<p class="MsoNormal">              ] ensure: [</p>
<p class="MsoNormal">                           Transcript show: 'x3']</p>
<p class="MsoNormal">] newProcess.</p>
<p class="MsoNormal">p resume.</p>
<p class="MsoNormal">Processor yield.</p>
<p class="MsoNormal">p terminate</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">===> x1</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The unwind procedure prints just x1 and skips not only x2 but x3 as well ! You'd like to see them all.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">ad 5) This happens in cases like (better save your image before trying this):</p>
<p class="MsoNormal">              [self error: 'e1'] ensure: [^2]        "discovered by Christoph Thiede"</p>
<p class="MsoNormal">and</p>
<p class="MsoNormal">              [self error: 'e1'] ensure: [self error: 'e2']</p>
<p class="MsoNormal">These are generally the types of situations causing the Unwind errors. The root cause is that the unwinding is done via simulation (#popTo) rather than 'directly'; the problem is during the simulated execution of unwind blocks a non-local
 return forwards the execution into a wrong stack - resulting in the Unwind errors.
</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">ad 6) I just prefer a unified approach... unless I somehow overlooked a reason for two different approaches (I hope not).</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">[1] http://forum.world.st/A-bug-in-active-process-termination-crashing-image-td5128186.html</p>
<p class="MsoNormal">[2] http://forum.world.st/Another-bug-in-Process-gt-gt-terminate-in-unwinding-contexts-td5128171.html#a5128178</p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>