sealed class Run extends Runnable with debug.REGISTRY.Debuggable
Manages the state of a running alternation construct whose
abstract syntax is syntax
. If registerWithDebugger
is true
then the alternation construct is registered with the debugger
while it runs. This is for in-extremis debugging
of deadlocking CSO code that includes alternations.
Alternations happen in four phases (these phases are almost the same for alt, prialt, serve and priserve constructs), namely: Registration, Waiting, Unregistration, and Execution.
- Registration: The current feasibility of all participating events is
recorded as
UNKNOWNSTATE
,INFEASIBLE
, orREADYSTATE
, and their associated ports are marked as being involved in this running alternation construct. An event for a port that is closed at this stage will never become feasible. An event is infeasible if its associated port has been closed, or if its associated guard is false. - Waiting: If, after registration, no
READYSTATE
event is present, but some events are still feasible, then the alternation will wait (with the appropriate deadline, if there's an after event; and sine-die otherwise) for a port to change state. If there's an after event and the wait timed-out, then the after event is marked to be executed. If no events are feasible by this phase, or if the last feasible event becomes infeasible as a consequence of a state change (because its port closed during the wait), then the orelse path is taken, to wit: the orelse event (if any) is marked to be executed. - Unregistration: All ports of all feasible events are now unregistered from their participation in this running alt. If during this phase any already-feasible events are found to be ready then one of them is chosen and marked for execution. The precise method of choice depends on whether or not the alternation construct is supposed to be fair. In this implementation all but serve alternations choose the first event (in order of appearance in the alternation) found to be ready during unregistration. (Unregistration of feasible events actually takes place in reverse order of appearance in the alternation, giving "higher priority" feasible events a little more time to become ready.)
- Execution: When all event ports have been unregistered, then:
- If a feasible event has been marked for execution, then it is executed; or
- If after has been marked for execution, then it is executed; or
- If orelse has been marked for execution, then it is executed (and if the executing alternative is a serve, the serve is terminated)
- If nothing has been marked for execution, then an alt or prialt will abort; and a serve or priserve will terminate.
The present implementation is highly unadventurous and may be less than optimally efficient, though it is (intended to be) scrutable. My experience has been that alternation is tricky to implement efficiently without introducing race conditions that are hard to track down.
Possible improvements/speedups include:
- Run the first event found to be ready during registration in an
priserve
orprialt
. - Give the programmer more control of the algorithm that chooses fairly between events
run during the execution of a
serve
. Theround-robin
method is not always effective -- particularly when certain patterns of guarded event are present in the alternation. - Distinguish between
alt
andprialt
implementation by using an efficient source of randomness to choose among events that become ready before unregistration.
@author Bernard Sufrin, Oxford, $Revision: 316 $, $Date: 2018-01-11 18:18:45 +0000 (Thu, 11 Jan 2018) $
- Alphabetic
- By Inheritance
- Run
- Debuggable
- Runnable
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Instance Constructors
-
new
Run(register: Boolean, syntax: Event, loc: SourceLocation.SourceLocation)
- register
Redundant in the current implementation.
- syntax
Abstract syntax of the alternation
- loc
Source loc'n of the alternation (implicit SourceLocation parameter to alt/prialt/serve/priserve)
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
alt(): Unit
Run this alternation as an alt
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
def
clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
-
def
getWaiting: Seq[Thread]
Returns
List(runner)
only if the alternation is waiting for an event to become ready; otherwiseList()
.Returns
List(runner)
only if the alternation is waiting for an event to become ready; otherwiseList()
.- Definition Classes
- Run → Debuggable
-
def
hasState: Boolean
This object has a state worth showing right now: false if showState will do no output.
This object has a state worth showing right now: false if showState will do no output.
- Definition Classes
- Debuggable
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
val
key: StateKey
This object's key in the registry (if non-negative)
This object's key in the registry (if non-negative)
- Definition Classes
- Debuggable
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
-
def
notifyPortEvent(theIndex: Int, state: PortState): Unit
Notification that its state of readiness changed: sent by a port referenced by the
theIndex
th event of this alternation.Notification that its state of readiness changed: sent by a port referenced by the
theIndex
th event of this alternation. OnlyCLOSEDSTATE
andREADYSTATE
are ever notified by channel implementations, because only these are of interest to an already-running alternation. -
def
prialt(): Unit
Run this alternation as a prialt
Run this alternation as a prialt
- Annotations
- @inline()
-
def
priserve(): Unit
Run this alternation as a priserve
-
def
register(): Unit
Register this object
Register this object
- Definition Classes
- Debuggable
-
def
serve(): Unit
Run this alternation as a serve
-
def
showState(out: PrintWriter): Unit
Invoked by the debugger to show the current state of this running alternation.
Invoked by the debugger to show the current state of this running alternation.
- Definition Classes
- Run → Debuggable
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
- Definition Classes
- Run → AnyRef → Any
-
def
unregister(): Unit
Unregister this object
Unregister this object
- Definition Classes
- Debuggable
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
def
withDebugger[T](condition: Boolean)(body: ⇒ T): T
Conditionally
register
this object with the debugger only for the duration of the evaluation ofbody
.Conditionally
register
this object with the debugger only for the duration of the evaluation ofbody
. To be used as a last resort for the exasperated CSO toolkit debugger.- Definition Classes
- Debuggable