Executing an EMont model

Executing a PQR Cluster

Only the leaf activities of a PQR cluster are eligible for execution with the restriction that leaf nodes must have a direct upwards path to the activity in the PQR cluster that has been activated.

Executing a Compound Cluster

A compound activity is comprised of a number of child activities that are performed in particular sequences. Executing a compound activity means that its child activities are executed until they are all done. A compound activity can be nested to arbitrary depths, that is, a compound activity can contain a compound activity, and so on. The nested activities form a compound cluster indicated with the OR annotation.

Just like leaf (Q - how) activities in a PQR cluster, an activity in a compound cluster takes conditions as input and produces updated conditions. But unlike a Q activity, a compound cluster activity is not triggered by conditions, instead the executing is determined by sequence relations, such as activity B follows (seq relation) activity A, or either A or (alt relation) B is chosen. A PQR cluster, indicated with EXOR, can be part of an activity sequence. Likewise, a leaf (Q - how) activity can be a compound cluster. In this way, a compound and a PQR cluster are nested in an alternating fashion.

The leaf (Q - how) activity value of the overarching PQR cluster is calculated after its compound activity, if any, terminates. This is solely done on the basis of the contributes and depends relations associated with the leaf activity. That is, no values from compound activities are propagated to an overarching PQR cluster.

Algorithm

Thread info

  • mode: enum of Running, Active, Joining (if needed), Suspended.
  • state: refers to the state leading via (conditional) edges to possibly multiple primitives in (zero or more) PQR and (zero or one) compound cluster of which one will be executed in the end.
  •  parent: refers to the parent (suspended) thread.
  • children: list of forked child threads.

Lists

  • Active list: list of active threads to be executed provided a primitive is eligible for execution. The Active list is searched for this primitive on a FCFS basis.

Pseudo code

create start thread and put it on the Active list

while (Active list ≠ empty) do

currentThread := get first eligible thread from Active list (exactly one primitive to be executed)
// a primitive is eligible for execution if:
// 1 – in case of a join, all sibling threads in joining (ready to join) state
// 2 - guard evaluates to true
// 3 – depends evaluates to true
// 4 – sync semaphore does not block
currentThread.mode := Running
while (currentThread.mode = Running) do
fork or join // fork en join are side effects of the transition to the primitive
execute the primitive, i.e., updating conditions
determine the next primitive(s) to be executed // should be zero or one primitive based on the four criteria
if (number of primitives = 0) then // a thread switch is needed because this thread cannot continue right now
currentThread.mode := Active
put currentThread of the Active list
elseif (primitive is part of PQR cluster) then // voluntary yield to let another thread seize control
currentThread.mode := Active
put currentThread on the Active list
elseif (primitive is part of the compound cluster) then
currentThread.state := end state of current primitive
else
// there is or should be no other case
fi
od

od <accesscontrol>Access:We got to move</accesscontrol>