[squeak-dev] Re: Setting a preempted process priority glitch
siguctua at gmail.com
Fri May 1 16:37:01 UTC 2009
2009/5/1 Igor Stasenko <siguctua at gmail.com>:
> 2009/5/1 Andreas Raab <andreas.raab at gmx.de>:
>> Igor Stasenko wrote:
>>> This issue shows, that comment in Process>>#terminate, lying to us:
>>> "Since the receiver is not the active process, drop its priority to
>>> rock-bottom so that
>>> it doesn't accidentally preempt the process that is trying to terminate
>>> priority := 10.
>> It's actually saying the right thing. What this code is trying to avoid is
>> that a process waiting on some semaphore (like a network thread) starts
>> "running away" when it receives a signal (we've seen this happening in
>> several cases). Contrary to your example the terminating process has no wait
>> during which the terminated process could run at lower priority. And if the
>> terminated process were at higher priority and not currently waiting, then
>> obviously the terminating process would not execute. So it all works out.
> if terminated process is at higher priority and not waiting then it:
> a) should run now , instead of process which tries to terminate it
> b) should be suspended
> but there are always a chance that:
> c) another, higher priority process interrupts current process and
> doing something which makes terminated process to run again.
> in this case, a terminated process can have any priority & state, it
> will not save you from other's process intrusion to do anything with
> it (its really interesting to see what will happen if two different
> processes decide to terminate same process, and preempt each other
> during unwinding phase ;-) ). That's, to my thinking, can be avoided
> only by introducing an additional ivar to process, to test its state.
> And even, if higher priority don't does anything with terminated
> process, try this:
> | x procToTerminate intruder sema |
> sema := Semaphore new.
> x := nil.
> procToTerminate := [ x:= 1] fork.
> intruder := [ sema wait ] forkAt: Processor activePriority +1.
> "now suppose here we started a termination procedure ... "
> procToTerminate priority: 10.
> " and somewhere in the middle we got external signal (such as from
> Delay or Socket) "
> sema signal.
> x isNil
Actually to illustrate it more precisely replace 'x isNil' to
>> But the real fix for these issues is atomic suspend, i.e., instead of:
>> priority := 10.
>> myList ifNotNil: [
>> myList remove: self ifAbsent: .
>> "Figure out if the receiver was terminated while waiting on a
>> inSema := myList class == Semaphore.
>> myList := nil].
>> this needs to be:
>> oldList := self suspend.
>> inSema := oldList class == Semaphore.
> yes, but before that, i would insert:
> | canTerminate |
> Processor interruptWith: [
> canTerminate := self isTerminating not.
> self terminating: true.
> canTerminate ifTrue: [
> .. unwind .. blablabla
>> - Andreas
> Best regards,
> Igor Stasenko AKA sig.
Igor Stasenko AKA sig.
More information about the Squeak-dev