Trying to understand unpreemptive execution/#valueNoContextSwitch

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Trying to understand unpreemptive execution/#valueNoContextSwitch

Christoph Thiede

Hi all,


in the context of the current Transcript debate [1], I am trying to figure out whether, and why Marcel's proposed implementation of <noContextSwitch> [2] could work.


As a minimum example to test #valueNoContextSwitch, I tried the following:


"Try to run this infinite loop unpreemptively."

[

[[false] whileFalse] valueNoContextSwitch.

self inform: #done

] forkAt: Processor userBackgroundPriority.


Now I would have expected my image (its UI process) to freeze while p2 is running unpreemptively. But - nothing happens, i.e., all other processes are still activated! I also exchanged valueNoContextSwitch with valueUninterruptably (which I implemented using primitive 123 analogously to <noContextSwitch>) with the same result.


Here is my question: Am I misunderstanding the concept of unpreemptive/uninterruptable execution (are those two terms really synonyms?), or is unpreempted execution broken?

Assuming the former is the case, what else would be a good and simple way to find out if a process is being run unpreemptively?

And do we have any good documentation of this concept - self-documenting tests will be preferred? :-)


Best,

Christoph


[1] http://forum.world.st/Transcript-error-when-forceUpdate-false-td5126397.html



Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Trying to understand unpreemptive execution/#valueNoContextSwitch

Eliot Miranda-2
Hi Christoph,

On Mon, Feb 1, 2021 at 8:29 AM Thiede, Christoph <[hidden email]> wrote:

Hi all,


in the context of the current Transcript debate [1], I am trying to figure out whether, and why Marcel's proposed implementation of <noContextSwitch> [2] could work.


As a minimum example to test #valueNoContextSwitch, I tried the following:


"Try to run this infinite loop unpreemptively."

[

[[false] whileFalse] valueNoContextSwitch.

self inform: #done

] forkAt: Processor userBackgroundPriority.


Now I would have expected my image (its UI process) to freeze while p2 is running unpreemptively.


RTFM :-)

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.

i.e. this has an effect only on activating the block.  Once the block is running preemption is still possible.  All that it guarantees is that no preemption is possible from immediately before the send of valueNoContextSwitch to the first send in the block activation.  

But - nothing happens, i.e., all other processes are still activated! I also exchanged valueNoContextSwitch with valueUninterruptably (which I implemented using primitive 123 analogously to <noContextSwitch>) with the same result.


Here is my question: Am I misunderstanding the concept of unpreemptive/uninterruptable execution (are those two terms really synonyms?), or is unpreempted execution broken?


They're not synonyms, but neither of them apply to valueNoContextSwitch, nor my proposed pragma which should perhaps be <noContextSwitchOnActivation>

Assuming the former is the case, what else would be a good and simple way to find out if a process is being run unpreemptively?

And do we have any good documentation of this concept - self-documenting tests will be preferred? :-)


A test might have a lower priority process in some kind of loop that invokes a block via valueNoContextSwitch, or calls a method marked with <noContextSwitchOnActivation>. This process would be run from a higher priority process that would loop waiting for a short delay (1 microsecond?).  Ocne past its delay it would preempt the lower priority process, sample its pc and fail if the pc was the first pc of valueNoContextSwitch or a method marked with <noContextSwitchOnActivation>.

A test with two such lower priority processes could be used to test processPreemptionYields == false. If processPreemptionYields == true then every preemption would cause the two lower priority processes to switch order. If processPreemptionYields == false the second one would not run until the first one yielded explicitly, or waited, etc.




--
_,,,^..^,,,_
best, Eliot