[Cuis-dev] FW: FW: FW: Freezing UI - can't interrupt via Alt+.

Juan Vuletich juan at cuis.st
Wed Aug 10 06:41:39 PDT 2022


Hi Jaromir,

On 8/10/2022 9:24 AM, Jaromir Matas via Cuis-dev wrote:
>
> Hi Juan,
>
> I very much like your simplifying the code opening a debugger :)
>
> I'm still just skimming the surface of the UI implementation but I'd 
> like to ask a few questions:
>
> (1) why is there Object >> #runningWorld
>
> - wouldn't sending `UISupervisor runningWorld` instead of `true 
> runningWorld` be sufficient e.g. in Debugger >> 
> #openWindowLabel:usePreDebugWindow:preDebugMessage:?
>

Yes, of course. The implementation in Object is just to avoid creating 
references to UISupervisor all over the place, in case some day we want 
to replace it with something else. It is just that I wasn't so sure 
about UISupervisor when I created it. Not a big deal, IMO.

> (2) Why not define UISupervisor >> runningWorld via #animatedUIOf: to 
> avoid code duplicity?
>
> UISupervisor >> runningWorld
>
>                 "
>
>                 UISupervisor runningWorld
>
>                 [ UISupervisor runningWorld print ] fork
>
>                 "
>
>                 ^self animatedUIOf: Processor activeProcess
>

Yeah. Good idea. Just post the .cs, so it has your initials :)

> (3) I understand your intention when you lowered the former UI 
> process's priority in #spawnNewMorphicProcessFor: by one; I believe it 
> was in response to this example:
>
> [1/0] fork.
>
> 5 seconds asDelay wait.
>
> self error: 'error'
>
> I've been wondering whether it's still relevant after your most recent 
> changes - and unfortunately it seems that it is: changing the former 
> UI process's priority back to the active priority will cause redraw 
> glitches (e.g. Transcript background color in Dark mode won't display 
> properly).
>
> However, there seems to be a very similar redraw blip *despite* the 
> lower priority tweak when running e.g.
>
> [1/0] fork.
>
> [1/0] fork
>
> ... the Transcript window won't get redrawn correctly in the Dark 
> mode: it won't change its background color properly. It puzzles me why 
> the Transcript window is the only one affected.
>

The Transcript is special. It will do the same in any Theme, although 
the difference may be less obvious. Try `1 to: 4 do: [ :i | i print. 
100000 factorial ]` in a Workspace. Do it with another window partially 
covering the Transcript. The thing here is that the Transcript gets 
immediate updates, without waiting for the next Morphic cycle. This is 
extremely useful for debugging, and especially for debugging Morphic 
itself. Browse a bit Transcript and you'll see.

The reason to lower the older Morphic priority is to guarantee a 
responsive UI, a focus of yours in the last months. Besides, given that 
(see below) in Cuis two processes of the same priority can interrupt 
each other at any time, and given that Morphic is not thread safe, then, 
as we want the old Morphic process to finish its stuff (as many of your 
examples required), we need to make that with a lower priority than the 
main UI process, to reduce the risk of the old process breaking state 
needed by the new one.

> What I'm trying to figure out is: if the computation carried out by 
> this former UI process involves references to Processor activePriority 
> the priority-lowering tweak may change the semantics of a computation 
> involving forking processes at different relative priorities (in other 
> words changing the priority of the process in the middle of the 
> computation by an *unrelated* "outsider" process feels dangerous); 
> just a theoretical idea though, unfortunately I don't have any 
> practical example or any further suggestion; I'll return to this later 
> after some more educating myself :)
>

But it is not an *unrelated* process. It is the UISupervisor, who 
created it in the first place, gave it the chore of running the World, 
and is now replacing it with a new one.

> About the processPreemptionYields flag:
>
> > I think it would be important to understand why would someone want 
> #processPreemptionYields = false. Their reasons for requesting a 
> process to never yield to others of same priority (even if some higher 
> process wakes up in between) may also mean they don't want new UI 
> processes to be started so lightly.
>
> Here's Eliot's explanation why he chose #processPreemptionYields = 
> false over the previous functionality: 
> https://forum.world.st/about-signal-tp5109735p5109862.html
>

I know. I've been here since before Squeak ran Morphic, and it was MVC 
only. I understand MVC process scheduling in Smalltalk-80 and its 
evolution through Morphic.

#processPreemptionYields = false is the intended behavior in 
Smalltalk-80. In Smalltalk-80 a process can only be preempted by one of 
a higher priority. This means that no real access protection is needed 
between processes of the same priority (given that they only #yield at 
safe places). This is akin to Corroutines (and #resumeNext semantics). 
But the original Squeak VM, when resuming a high priority process, will 
put the active process at the back of the process queue, possibly 
breaking older code. This is the #processPreemptionYields = true 
behavior. Squeak needed then to adapt to this behavior. Much later, 
Eliot added the #processPeemptionYields = false to restore the original 
Smalltalk-80 intended behavior, which could be safer for code unaware of 
these issues.

In Cuis, no assumption is made. The way to protect access to Morphic 
state is to call #whenUIinSafeState: . So, #processPreemptionYields can 
be set to true. I believe this is what most people would expect in these 
days. The last mainstream OS that switched from "cooperative 
multitasking" to "preemptive multitasking" was MacOS about 20 years ago!

> My understanding is he simply thinks #processPreemptionYields = true 
> produces an inconsistent/erroneous behavior in the sense that unless a 
> process *explicitly* yields control it should stay in control (unless 
> preempted by a higher priority process in which case it should get 
> back control once the higher priority process gives up control, i.e. 
> stay at the front of the run queue).
>
> In case of Squeak (which is on #processPreemptionYields = false) each 
> world cycle does contain an explicit yield anyway so opening each 
> debugger in a new UI doesn't seem to clash with this stricter 
> cooperative-within-priorities scheduling approach imho :)
>
> A while ago I asked Marcel about the preemption modes and the answer 
> was (roughly) that #processPreemptionYields = false offers more 
> predictability (understandably) plus something about thread-safe-ness 
> of Morphic structures (which is still way beyond my skills level).
>
> Is there a reason why you'd prefer #processPreemptionYields = true or 
> is it just for historic reasons? ("why fix something that works" type 
> of situation? :) )
>

Absolutely the contrary!

#processPreemptionYields = false is to keep the Smalltalk-80 cooperative 
multitasking style that was widespread until mid 90's, when Linux and 
Windows made the transition, followed a few years later by MacOS. In 
Cuis we explicitly made the change to #processPreemptionYields = true 
about a decade ago to be in line with modern practice. In doing so, I 
needed to come up with #whenUIinSafeState: and make sure that nothing 
broke. Another situation where Cuis favors progress in spite of back 
compatibility.

> Thanks again very much for discussing these issues!
>
> Best regards,
>
> Jaromir
>
> --
>
> *Jaromír Matas*
>
> mail at jaromir.net
>
>

Cheers,

-- 
Juan Vuletich
cuis.st
github.com/jvuletich
researchgate.net/profile/Juan-Vuletich
independent.academia.edu/JuanVuletich
patents.justia.com/inventor/juan-manuel-vuletich
linkedin.com/in/juan-vuletich-75611b3
twitter.com/JuanVuletich

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20220810/ec8a989e/attachment-0001.htm>


More information about the Cuis-dev mailing list