[Pkg] The Trunk: Kernel-eem.999.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Feb 19 07:03:43 UTC 2016
Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.999.mcz
==================== Summary ====================
Name: Kernel-eem.999
Author: eem
Time: 18 February 2016, 11:03:09.008076 pm
UUID: 30222068-755f-4637-bbbb-6f775291e746
Ancestors: Kernel-bf.998
Fix isSuspended (my last commit was a regression; I had confused isSuspended with isBlocked). Comment all the isFoo testing methods in process. Add isBlocked. Modify Process>>terminate to set the pc of the context of a process that is not auto-terminated to its endPC so that isTerminated and isSuspended can distinguish between processes either terminated or suspended.
=============== Diff against Kernel-bf.998 ===============
Item was added:
+ ----- Method: Process>>isBlocked (in category 'testing') -----
+ isBlocked
+ "A process is blocked if it is waiting on some list (i.e. a Semaphore), other than the runnable process lists."
+ | myPriority |
+ "Grab my prioirty now. Even though evaluation is strictly right-to-left, accessing Processor could involve a send."
+ myPriority := priority.
+ ^myList
+ ifNil: [false]
+ ifNotNil: [:list| list ~~ (Processor waitingProcessesAt: myPriority)]!
Item was added:
+ ----- Method: Process>>isRunnable (in category 'testing') -----
+ isRunnable
+ "A process is runnable if it is the active process or is on one of the runnable process lists."
+ | myPriority |
+ "Grab my prioirty now. Even though evaluation is strictly right-to-left, accessing Processor could involve a send."
+ myPriority := priority.
+ ^myList
+ ifNil: [^self == Processor activeProcess]
+ ifNotNil: [:list| list == (Processor waitingProcessesAt: myPriority)]!
Item was changed:
----- Method: Process>>isSuspended (in category 'testing') -----
isSuspended
+ "A process is suspended if it has been suspended with the suspend primitive.
+ It is distinguishable from the active process and a terminated process by
+ having a non-nil suspendedContext that is either not the bottom context
+ or has not reached its endPC."
+ ^nil == myList
+ and: [nil ~~ suspendedContext
+ and: [suspendedContext isBottomContext
+ ifTrue: [suspendedContext closure
+ ifNil: [suspendedContext methodClass ~~ Process
+ or: [suspendedContext selector ~~ #terminate]]
+ ifNotNil: [suspendedContext pc < suspendedContext closure endPC]]
+ ifFalse: [true]]]!
- "A process is suspended if it is waiting on some list, other than the runnable process lists."
- | myPriority |
- "Grab my prioirty now. Even though evaluation is strictly right-to-left, accessing Processor could involve a send."
- myPriority := priority.
- ^myList
- ifNil: [false]
- ifNotNil: [:list| list ~~ (Processor waitingProcessesAt: myPriority)]!
Item was changed:
----- Method: Process>>isTerminated (in category 'testing') -----
isTerminated
+ "Answer if the receiver is terminated, or at least terminating."
-
self isActiveProcess ifTrue: [^ false].
^suspendedContext isNil
or: ["If the suspendedContext is the bottomContext it is the block in Process>>newProcess.
+ If so, and the pc is at the endPC, the block has already sent and returned
- If so, and the pc is greater than the startpc, the block has alrteady sent and returned
from value and there is nothing more to do."
suspendedContext isBottomContext
+ and: [suspendedContext closure
+ ifNil: [suspendedContext methodClass == Process
+ and: [suspendedContext selector == #terminate]]
+ ifNotNil: [suspendedContext pc >= suspendedContext closure endPC]]]!
- and: [suspendedContext pc > suspendedContext startpc]]!
Item was changed:
----- Method: Process>>terminate (in category 'changing process state') -----
terminate
"Stop the process that the receiver represents forever. Unwind to execute pending ensure:/ifCurtailed: blocks before terminating."
| ctxt unwindBlock oldList |
self isActiveProcess ifTrue: [
ctxt := thisContext.
[ ctxt := ctxt findNextUnwindContextUpTo: nil.
ctxt isNil
] whileFalse: [
(ctxt tempAt: 2) ifNil:[
ctxt tempAt: 2 put: nil.
unwindBlock := ctxt tempAt: 1.
thisContext terminateTo: ctxt.
unwindBlock value].
].
thisContext terminateTo: nil.
self suspend.
] ifFalse:[
"Always suspend the process first so it doesn't accidentally get woken up"
oldList := self suspend.
suspendedContext ifNotNil:[
"Figure out if we are terminating a process that is in the ensure: block of a critical section.
In this case, if the block has made progress, pop the suspendedContext so that we leave the
ensure: block inside the critical: without signaling the semaphore/exiting the primitive section,
since presumably this has already happened."
(suspendedContext isClosureContext
and: [(suspendedContext method pragmaAt: #criticalSection) notNil
and: [suspendedContext startpc > suspendedContext closure startpc]]) ifTrue:
[suspendedContext := suspendedContext home].
"If we are terminating a process halfways through an unwind, try
to complete that unwind block first."
(suspendedContext findNextUnwindContextUpTo: nil) ifNotNil:
[:outer|
(suspendedContext findContextSuchThat:[:c| c closure == (outer tempAt: 1)]) ifNotNil:
[:inner| "This is an unwind block currently under evaluation"
suspendedContext runUntilErrorOrReturnFrom: inner]].
ctxt := self popTo: suspendedContext bottomContext.
ctxt == suspendedContext bottomContext ifFalse:
+ [self debug: ctxt title: 'Unwind error during termination'].
+ "Set the context to its endPC for the benefit of isTerminated."
+ ctxt pc: ctxt endPC]]!
- [self debug: ctxt title: 'Unwind error during termination']]]!
More information about the Packages
mailing list