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
^[^ Jaromir
|
Free forum by Nabble | Edit this page |