![]() |
![]() |
![]() |
![]() |
![]() |
General Purpose Operators
Introduction
The abstract data type IdNode described in this section introduces a number of operators that may be used to simplify an SDL system. The simplifications will give both reduced code size and higher speed of execution for your application, as well as make debugging easier. This ADT cannot be used in OS integrations or with Cmicro.
The operators may be grouped into two groups:
- "Almost SDL operations", that is, operators that are easy to understand in an SDL context, but which are not available in SDL. Examples are the possibility to enumerate all active instances of a certain process instance set, or to count the number of signals in an input port.
- Operators that handle implementation aspects. An example is an operator to reuse memory in avail lists.
Type IdNode
This abstract data type becomes available by inserting the analyzer include:
/*#include 'idnode.pr'*/This abstract data type file introduces three SDL sorts called PrsIdNode, PrdIdNode, and SignalIdNode in SDL. These sort correspond to the types xPrsIdNode, xPrdIdNode, and xSignalIdNode in C, which are used to represent the symbol table in the generated application. The symbol table, which is a tree, will contain the static information about the SDL system during the execution of the generated program.
Is is possible to refer to processes, procedures, and signals (among others) using the following the names:
yPrsN_ProcessName or &yPrsR_ProcessNameyPrdN_ProcedureName or &yPrdR_ProcedureNameySigN_SignalName or &ySigR_SignalNamewhere ProcessName, ProcedureName, and SignalName should be replaced by the name of the process, procedure, or signal with prefix, or by the name given to the unit in a #NAME directive. To obtain a name of a unit with prefix the directive #SDL may be used:
yPrsN_#(ProcessName) or &yPrsR_#(ProcessName)To avoid problems when separate generation is to be used, the &yPrsR_... syntax is recommended.
The #SDL directive is not always possible to use. It will look for an entity with the specified name in the current scope unit (where the #SDL directive is used) and outwards in the scope hierarchy. So, for example, if the reference for a process is to be used in a process defined in another block, a #SDL directive cannot be used for the referenced process. The name of the referenced process ought then to be given in a #NAME directive.
If separate generation is used there may be more problems to access these references. The variables will be defined in the compilation unit where the entity they represent is defined.
- The xPrsIdNode for a process will be defined in the file containing the code for the block enclosing the process.
- The xPrdIdNode for a procedure will be defined in the file containing code for the enclosing unit.
- The xSignalIdNode for a signal will be defined in the file containing code for the enclosing system, block, or process.
A reference is visible in the compilation unit (file) where it is defined and in all subunits to the unit, as a compilation unit will include the .h file of all its parent units.
Problems occur when we want to use a reference in a place where it is not visible, for example using an xPrsIdNode for a process defined in a separate block, in a process in another block. All references are, however, extern, which makes it possible for a user to introduce an appropriate extern definition (in a #CODE directive) himself in the compilation units where it is needed.
/*#CODE#HEADINGextern XCONST struct xPrsIdStruct yPrsR_ProcessName;*/To know the name of the referenced process, a #NAME directive ought to be used.
Such extern definitions introduce dependencies between otherwise independent compilation units. It is your responsibility completely to maintain these dependencies.
Available Operators
GetIdNode: PId -> PrsIdNode;
This operator takes a PId value and returns a reference to the PrsIdNode that represents the process type. PrsIdNode values are not useful for anything except as parameters to the operators discussed here.
Kill: PId -> PId;
The Kill operator can be used to stop another process instance. In SDL a process instance may only stop itself. This operator has exactly the same effect as if the process instance given as parameter executed a stop operation. The Kill operator always returns the value null.
KillAll: PrsIdNode -> Integer;
This operator takes a reference to an PrsIdNode representing a process type and will kill all the instances of the specified process type. The effect is the same as if all the instances executed stop operations. The operator returns the number of "killed" process instances.
FirstPId: PrsdNode -> PId;
See SucPId: PId -> PId; (next).
SucPId: PId -> PId;
This operator, together with FirstPId, are intended to be used to enumerate all process instances of the process type referenced by the PrsIdNode given as parameter to FirstPId. FirstPId should be given a reference to an PrsIdNode for a process type and returns the first (last created) process instance. SucPId should be given a PId value and will return the next PId for the given process type.
InputPortLength: PId -> Integer;
This operator returns the number of signals in the input port of the given process instance.
InputPortLength: PId, SignalIdNode -> Integer;
This operator returns the number of signals, of the signal type given as IdNode parameter, that are present in the input port of the given process instance. The SignalIdNode parameter should refer to a SignalIdNode that represents a signal or a timer.
NoOfProcesses: PrsIdNode -> Integer;
This operator should be given a reference to an PrsIdNode representing a process instance set and will return the number of active instances of this instance set.
IsStopped: PId -> Boolean;
The operator may be used to determine if a PId value refers to a process instance that is active or has executed a stop operation.
Broadcast: PrsIdNode, SignalIdNode, PId -> Integer;
This operator may be used to send one signal (without parameters) to each active process instance of a specified process instance set. The value of the third parameter, of type PId, will be used as sender in the signals. The result of the operator is the number of signals that are sent during this operation, i.e. the number of active process instances of the specified type.
FreeAvailList: PrsIdNode -> Integer and PrdIdNode -> Integer and SignalIdNode -> Integer
The FreeAvailList operator has no meaning in the SDL Explorer. It can be used but will in the Explorer be a null action.
The operator takes a reference to an IdNode (of one of the three type above) that represents a process, a procedure, or a signal and returns the memory in the avail list for the specified IdNode to the free memory by calling the sctOS function xFree. The function xFree uses the C standard function 'free' to release the memory. The FreeAvailList operator requires thus that free really releases the memory in such a way that it can be reused in subsequent memory allocations. Otherwise the operator is meaningless.
FreeAvailList is intended to be applied for reusing memory allocated for processes, procedures, and signals used only during a start-up phase. If the system, for example, contains a process used only during start-up, that is, all instances of this process perform stop actions early during the execution and no more processes will be created later, then the memory for these instances can be reused.
This operator should only be used as one of the last resorts in the process of minimizing the memory requirements of an application.
Connection to Monitor
In the trace output, operators like Kill and Broadcast will produce trace messages exactly in the same way as the equivalent Stop operation and the sequence of Output operations.
http://www.ibm.com/rational |
![]() |
![]() |
![]() |
![]() |