• No results found

Relevant Language Constructs

2.3 The Cal Actor Language

2.3.1 Relevant Language Constructs

A CAL actor executes by firing actions. An action describes the relation between input and output ports, and when an action fires, it may consume tokens from input ports, produce tokens to output ports, and modify the state of the actor. The token rates of the actions are fixed, and are defined in the program description, as an example, consider the following action which reads two tokens from input A and writes one token to port C. actor actorName ( ) uint A ==> uint C :

add : action A : [ a , b ] ==> C : [ c ] do

c := a+b ; end end

If this action is the only action of the actor, the actor is obviously SDF as the token rate is static for each firing; this is true for any action. The dy- namic behavior of a CAL actor appears from the interaction and scheduling of the various actions the actor contains. This scheduling can depend on 1) the state variables of the actor, 2) the action scheduler, and 3) input values.

Firing rules The state variables are, as the name hints, variables that

keep their value between action firings, and are therefore part of the actor’s state. A state variable is used to store information that is needed between action firings, whether it is data or control. The variable previous in the actor in Figure 2.1 is an example of a state variable that is used for the actual data processing. A state variable may also keep control information; this simply means that the variable is used in the firing rules, called guard expressions, of an action; as shown in the following example.

actor actorName ( ) uint I n p u t ==> uint Output : uint c o u n t := 0 ; action I n p u t : [ x ] ==> Output : [ x ] guard c o u n t < 64 do . . . end end

The other part of the actor state is described by the action scheduler. This construct, if present, is (typically) a Finite State Machine (FSM) which restricts when action may fire. The FSM describes a set of states and the transitions between these states correspond to actions; only actions corre- sponding to outgoing transitions of a specific state may fire in that state. The FSM, as such, already describes the order in which actions may fire and also shows the states where a scheduling decision based on a guard is needed, as such states have more than one outgoing transitions. While the FSM also could be implemented using state variables, from a scheduling point of view, the FSM is more practical as it describes the intention of the programmer. An example of the FSM scheduler can be seen in Figure 2.1.

Except for the actor state, the scheduling of actions may depend on the inputs of an actor. An action guard may directly refer to a value on an input port, which means that the token is read but only removed from the queue if the guard evaluates to true and the action fires. This is called a

peek and can be used to implement behavior where the appropriate action

is schedules based on the value of an input token. Consider the following actions as an example.

actor actorName ( ) uint A, uint B ==> uint C : d i v i d e : action A : [ x ] , B : [ y ] ==> C : [ x /y ] guard y != 0 end s k i p : action A : [ x ] , B : [ y ] ==> guard y = 0 end end

This simple actor, divides a stream of values by two, but avoids division by zero, by skipping the pairs where the denominator has a zero value. A guard may also depend on an input value that is first read to a state variable, technically, the guard simply uses the value of the state variable, but from a scheduling point of view, the value of the state variable is now much more difficult to predict.

The guard expression is the explicit part of the firing rules. For an action to fire, the guard expression must be evaluated to true, but there must also be a sufficient number of input tokens available, and in a practical implementation with limited buffer sizes, enough space on the output queues. As the actions have fixed token rates, it is trivial to extend the firing rules with the check for available inputs and output buffer space.

Special properties So far, the discussion has concerned the basic con-

constructed from these, it will have different properties, and may conform to more restricted MoCs than DPN. These can also be used to construct actors with more interesting, but also more difficult to handle, properties that are a result of firing rules that are nondeterminate or not mutually exclusive.

A nondeterministic actor can simply be created by having two actions that can be enabled simultaneously, which means that correct behavior is preserved if either of the actions is fired. Nondeterminism is useful for some actors when the programmer does not want to over specify the operation; consider the following actor as an example.

actor actorName ( ) uint A, uint B ==> uint C : one : action A : [ x ] ==> C : [ x ] end

t h e O t h e r : action B : [ x ] ==> C : [ x ] end end

In this actor, if tokens are available on both input channels, the choice between the actions one or theOther is not present in the actor description. This kind of an actor has both desired and non wanted properties; the actor is flexible as it can respond to input on any of the inputs at any point in time, on the other hand, if the input queues are constantly filled with more data, the actor may decide to only server one of the inputs and never choose the other one. Nondeterminism can be identified by comparing the guards of actions that can fire in the same state, if the actions have mutually exclusive guards, the actor is deterministic.

Another related property is when the firing rules depend on a volatile property which means that which action will fire depends on the point in time when the firing rules are evaluated. Time-dependent behavior appears when a lower priority action may fire when the other action does not have sufficient inputs. This happens when the guards of two actions are not mutually exclusive but the choice of action is specified by priorities. The following example shows an actor where one action fires as long as there is input while the other becomes enabled when the input is empty.

actor actorName ( ) uint A, uint B ==> uint C : one : action A : [ x ] ==> C : [ x ] end

two : action ==> C : [ 0 ] end

p r i o r i t y one > two ; end

end

It is important to identify time-dependent actors when analyzing schedul- ing properties of actors; a method for identifying time-dependent actors is presented by Wipliez et al. in [124]. Time-dependent actors are related

to the property of monotonicity; if an actor produces a specific output se- quence for one input, adding more input tokens does not simply mean that the output will be appended with more tokens.

The properties presented, are relevant for scheduling actors and actor partitions. For a scheduler to be complete, it must take into account data dependent firing rules, nondeterministic actors, and time-dependent behav- ior. A scheduling model must either verify that these properties are not present in the model or that these are preserved in the resulting scheduler such that the new model accepts all the input sequences the original program accepted.