[squeak-dev] Process >> priority: behavior grossly incorrect, Transcript losing output
Jaromir
m at jaromir.net
Sat Feb 6 08:37:56 UTC 2021
In the following example higher priority process keeps waiting in the
ProcessorScheduler queue until lower priority process suspends!
Transcript flush; cr.
*Processor activeProcess priority: 42.
[ Transcript nextPut: $A ] forkAt: 41.
Processor activeProcess priority: 40.*
Transcript nextPut: $B; flush.
1000 factorial.
Transcript nextPut: $C; flush.
1000 factorial.
Transcript nextPut: $D; flush.
10 milliSeconds wait. "suspends the active process"
Transcript nextPut: $E; flush.
Answers:
BCDAE
BCDAE
BCDE "here A even lost!"
BCDAE
BCDAE
BCDAE
BCDAE
BCDAE
Increasing the lenght of computation by doing 20000 factorial shows
interrupts work and suspend the rogue process:
BCDAE
BACDE
BCADE
BCDE "A lost again"
BACDE
BCDAE
BCDAE
Reason: the #priority: method won't make sure the active process doesn't
jump over a scheduled process when lowering it's priority - as a result the
active process will continue running until it suspends and won't let the
higher priority process a chance to run.
priority: anInteger
"Set the receiver's priority to anInteger."
(anInteger >= Processor lowestPriority and:[anInteger <= Processor
highestPriority])
ifTrue: [priority := anInteger]
ifFalse: [self error: 'Invalid priority: ', anInteger printString]
Proposed solution:
priority: anInteger
"Set the receiver's priority to anInteger."
(anInteger >= Processor lowestPriority and:[anInteger <= Processor
highestPriority])
ifTrue: [
priority := anInteger.
*(self isActiveProcess and: [anInteger < Processor nextReadyProcess
priority])
ifTrue: [ [self resume] fork. self suspend ] ]*
ifFalse: [self error: 'Invalid priority: ', anInteger printString]
The problem with this solution is the #nextReadyProcess may get interrupted
in the middle which may make it's answer usless. So I guess either this
whole method should run as a primitive or in the interim, always force the
active process suspend momentarily to let ProcessorScheduler do the job:
priority: anInteger
"Set the receiver's priority to anInteger."
(anInteger >= Processor lowestPriority and:[anInteger <= Processor
highestPriority])
ifTrue: [
priority := anInteger.
*self isActiveProcess ifTrue: [ [self resume] fork. self suspend ] ]*
ifFalse: [self error: 'Invalid priority: ', anInteger printString]
Impact: at least two methods use this type of priority switching:
#valueUnpreemptively and #valueAt: and their behavior is impacted the same
way.
Transcript flush; cr.
*[
[ Transcript nextPut: $A ] forkAt: 41.
] valueUnpreemptively.*
Transcript nextPut: $B; flush.
20000 factorial.
Transcript nextPut: $C; flush.
20000 factorial.
Transcript nextPut: $D; flush.
10 milliSeconds wait.
Transcript nextPut: $E; flush.
Answers again:
BCDAE
BCDAE
BCDE
BCADE
BCDAE
BCADE
BCDAE
BCDE
BCDAE
BACDE
On top of that Transcript loses some output intermittently - I'm not sure if
it's related or a separate issue.
Image
-----
C:\Users\mail\Squeak\Squeak6.0alpha-20182-64bit-superFRESH\Squeak6.0alpha-20182-64bit.image
Squeak6.0alpha latest update: #20182
with all default settings including:
Smalltalk vm processPreemptionYields = false
TranscriptStream forceUpdate = true
Related discussion:
http://forum.world.st/The-Inbox-Compiler-mt-456-mcz-td5126723.html
--
Sent from: http://forum.world.st/Squeak-Dev-f45488.html
More information about the Squeak-dev
mailing list
|