>From 6c66623ed6632180d44e9062e829511e68a547e9 Mon Sep 17 00:00:00 2001 From: Gwenael Casaccio Date: Tue, 25 Mar 2014 11:20:07 +0100 Subject: [PATCH 6/6] Fix Process creation the priority is correctly set, if the new process is suspended the current process is not yielded. Some priority needs to be checked we need that while terminate the process all the ensure blocks are executed. Thus a special context is created with it we are sure the ensure blocks will be executed. --- ChangeLog | 7 ++++++ kernel/MthContext.st | 17 +++++++++++++++ kernel/Process.st | 61 ++++++++++++++++++---------------------------------- kernel/SysExcept.st | 5 +++++ 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5178b01..f91e9ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2014-03-25 Gwenael Casaccio + + * kernel/Process.st: Change the process creation it set on the right priority queue, + the previous implementation sets it on a wrong priority queue. + * kernel/MthContext.st: Add a new MethodContext builder. + * kernel/SysExcept.st: ProcessBeingTerminated>>defaultHandler will execute all the ensure blocks. + 2014-03-24 Gwenael Casaccio * kernel/Process.st: Fix the implementation of Process>>evaluate:ifNotTerminated: use diff --git a/kernel/MthContext.st b/kernel/MthContext.st index 4f6af36..00cafde 100644 --- a/kernel/MthContext.st +++ b/kernel/MthContext.st @@ -41,6 +41,23 @@ ContextPart subclass: MethodContext [ bits of information about the execution environment, and contain the execution stack.'> + MethodContext class >> stack: size flags: anInteger method: aMethod ip: anIpInteger sp: anSpInteger [ + + + ^ (self new: size) + flag: anInteger method: aMethod ip: anIpInteger sp: anSpInteger; + yourself + ] + + flag: anInteger method: aMethod ip: anIpInteger sp: anSpInteger [ + + + flags := anInteger. + ip := anIpInteger. + sp := anSpInteger. + method := aMethod. + ] + printOn: aStream [ "Print a representation for the receiver on aStream" diff --git a/kernel/Process.st b/kernel/Process.st index d5931fb..aa30c06 100644 --- a/kernel/Process.st +++ b/kernel/Process.st @@ -52,6 +52,16 @@ can suspend themselves and resume themselves however they wish.'> suspend: aBoolean ] + Process class >> termination [ + + + Termination isNil ifFalse: [ ^ Termination ]. + ^ [ + Termination isNil ifTrue: [ Termination := MethodContext stack: 4 flags: 6 method: UndefinedObject>>#__terminate ip: 0 sp: -1 ]. + Termination + ] valueWithoutPreemption + ] + debugger [ "Return the object in charge of debugging the receiver. This always returns nil unless the DebugTools package is loaded." @@ -367,46 +377,17 @@ can suspend themselves and resume themselves however they wish.'> ] onBlock: aBlockClosure at: aPriority suspend: aBoolean [ - - "It is important to retrieve this before we start the - process, because we want to choose whether to continue - running the new process based on the *old* activePriority, - not the one of the new process which is the maximum one." - - | closure activePriority | - activePriority := Processor activePriority. - closure := - [[[ - "#priority: is inlined for two reasons. First, to be able to - suspend the process, and second because we need to invert - the test on activePriority! This because here we may want to - yield to the creator, while in #priority: we may want to yield - to the process whose priority was changed." - priority := aPriority. - aBoolean - ifTrue: [self suspend] - ifFalse: [ - aPriority < activePriority ifTrue: [ Processor yield ] ]. - aBlockClosure value] - on: SystemExceptions.ProcessBeingTerminated - do: - [:sig | - "If we terminate in the handler, the 'ensure' blocks are not - evaluated. Instead, if the handler returns, the unwinding - is done properly." - - sig return]] - ensure: [self primTerminate]]. - - "Start the Process immediately so that we get into the - #on:do: handler. Otherwise, we will not be able to - terminate the process with #terminate. The #resume will - preempt the forking process." - suspendedContext := closure asContext: nil. - priority := Processor unpreemptedPriority. - self - addToBeFinalized; - resume + + + | closure | + closure := [ [ aBlockClosure value ] ensure: [ self primTerminate ] ]. + " With the context created by terminate the 'ensure' blocks not + evaluated. " + suspendedContext := closure asContext: (self class termination) copy. + priority := aPriority. + self addToBeFinalized. + aBoolean ifTrue: [ ^ self ]. + self resume ] isActive [ diff --git a/kernel/SysExcept.st b/kernel/SysExcept.st index 1adcb6f..80d61a9 100644 --- a/kernel/SysExcept.st +++ b/kernel/SysExcept.st @@ -298,6 +298,11 @@ Notification subclass: ProcessBeingTerminated [ semaphore := aSemaphore ] + + defaultAction [ + + thisContext environment continue: nil + ] ] ] -- 1.8.3.2