[squeak-dev] Transcript error when forceUpdate: false (?)

Eliot Miranda eliot.miranda at gmail.com
Tue Jan 26 22:45:55 UTC 2021


Hi Marcel, Hi All,

On Mon, Jan 25, 2021 at 3:26 AM Marcel Taeumel <marcel.taeumel at hpi.de>
wrote:

> > It's simply not thread-safe.
>
> Hmm... in particular, there is a side effect (i.e. layout update) in the
> window's pluggable text morph. Even if #forceUpdate is false.
>
> In #endEntry, we could check for "Processor activeProcess == Project
> current uiProcess" to then use "Project current addDeferredUIMessage..."
> automatically.
>

That gave me a scare.  At first I thought that the effectiveProcess changes
to ProcessorScheduler>>activeProcess could have made that expression no
longer thread safe.  But it isn't anyway, and the above is very bad style.
Let me explain.

The suspension points in the VM are
- the first bytecode of any non-quick method (following a primitive if it
has one)
- the first bytecode of any block
- a backward branch

In the JIT there are fewer suspension points:
- the first bytecode of any method containing a send other than #== and/or
#class (and given that ifNil:ifNotNil: is inlined into a send of #== and
jumps, ifNil: sends don't count)
- the first bytecode of any block containing a send other than #== and/or
#class
- a backward branch

So given

ProcessorScheduler>>#activeProcess
        "suspension point here on an interpreter VM, and the first time in
the JIT VM"
^activeProcess effectiveProcess

Process>>#effectiveProcess
        "suspension point here on an interpreter VM, and the first time in
the JIT VM"
^effectiveProcess ifNil: [self]

Project class>>#current
        "suspension point here on an interpreter VM, and the first time in
the JIT VM"
^CurrentProject

MVCProject>>#uiProcess
        "suspension point here on an interpreter VM, and the first time in
the JIT VM"
^ world activeControllerProcess

MorphicProject>>#uiProcess
        "no suspension point here on any VM obeying the blue-book spec"
^uiProcess

we can see that "Processor activeProcess == Project current uiProcess" is
not thread-safe in the interpreter; there is a suspension point in Project
current before CurrentProject is returned (but not in the JIT); there is a
suspension point in MVC in uiProcess.  There is a suspension point in
ProcessorScheduler>>#activeProcess
before the send of effectiveProcess to activeProcess, but since no data is
fetched until the process resumes this is harmless.  However, were the
expression written as "Project current uiProcess == Processor
activeProcess" then this would no longer be harmless.

So on all VMs this is not reliably thread-safe.  Even on the JIT VM the
first use of any method (except a doit) is interpreted.  Once the JIT VM,
once it has started up and the methods have been jitted, "Processor
activeProcess == Project current uiProcess" is thread-safe on Morphic, but
not on MVC.  So we really shouldn't be using things like this.  They'll
appear to work and in very rare circumstances they won't.  So let's please
use the proper construct, Mutex.


But that makes me realize that the effectiveProcess changes are unsafe on
an interpreter VM (and hence we're on;y getting away with it on the JIT
VM).  Se really need some way of saying that ProcessorScheduler>>#activeProcess
is atomic, e.g.

Process>>#effectiveProcess
        <noContextSwitch>
^effectiveProcess ifNil: [self]

But I don't know how to implement this right now.  Note that we do have

BlockClosure>>#valueNoContextSwitch
"An exact copy of BlockClosure>>value except that this version will not
preempt
the current process on block activation if a higher-priority process is
runnable.
Primitive. Essential."
<primitive: 221>
numArgs ~= 0 ifTrue:
[self numArgsError: 0].
self primitiveFailed

FullBlockClosure>>#valueNoContextSwitch
"An exact copy of BlockClosure>>value except that this version will not
preempt
the current process on block activation if a higher-priority process is
runnable.
Primitive. Essential."
<primitive: 209>
numArgs ~= 0 ifTrue:
[self numArgsError: 0].
self primitiveFailed

but the VM uses the primitive numbers to control context switching.  We
don't have a mechanism the VM can use to label a normal method such
as Process>>#effectiveProcess as not to allow an interrupt.


> Best,
> Marcel
>
> Am 23.01.2021 21:05:05 schrieb Levente Uzonyi <leves at caesar.elte.hu>:
> On Fri, 22 Jan 2021, tim Rowledge wrote:
>
> >
> >
> >> On 2021-01-22, at 5:26 PM, David T. Lewis wrote:
> >>
> >> On Fri, Jan 22, 2021 at 02:03:10PM -0600, jaromir wrote:
> >>> I ran the following in Squeak 5.3:
> >>>
> >>> TranscriptStream forceUpdate: false.
> >>> [ 10000 timesRepeat: [ Transcript show: 'x' ] ] forkAt: 39
> >>>
> >>> When the Transcript window fills up, 'Message not understood' and
> 'Assertion
> >>> failure' appear. I'm wondering is this a bug? Thanks. Jaromir
> >>>
> >>>
> >>>
> >>
> >> It certainly does appear to be a bug.
> >
> > We had some discussion about it not so long ago; you can't use the
> Transcript to log bugs from Seaside very well, for example. Background
> processes, mutexs, that sort of thing. IIRC Levente offered an explanation?
>
> It's simply not thread-safe.
> If you want it to be thread-safe, you can pass your message to the UI
> process to show it. Make sure your message is computed in its own process
> and is passed as a precomputed string to avoid other kinds of race
> conditions. E.g.:
>
> | theMessage |
> theMessage := 'Something very {1}.' format: { 'important' }.
> Project current addDeferredUIMessage: [ Transcript show: theMessage; cr ].
>
>
> Levente
>
> >
> >
> > tim
> > --
> > tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
> > The hardness of the butter is proportional to the softness of the bread.
>
>
>

-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20210126/55180947/attachment.html>


More information about the Squeak-dev mailing list