Dynamic Role Modeling with ObjecTime C

Category |  Purpose |  Intended Audience |  Applicable to |  Description |  Limitations |  See also

Category:

Top

Modeling

Purpose:

Top

This tech note provides a technique for using dynamic structure with the ObjecTime C product. This technique is loosely based on the C++ product's importation capabilities, but makes use of the facilities in the C product to mimic the frame services which are built into the C++ product.

Intended Audience:

Top

ObjecTime C Developers who require the use of dynamic structure, in the form of importation, but are restricted to using the C product with it's lack of frame services.

Applicable to:

Top

ObjecTime 5.2.1 and up

Description:

Top

Importation in Developer for C++

Top

There are a large number of situations that come up while developing a system with ObjecTime Developer best addressed through the use of importation. This facility, part of ObjecTime Developer for C++, has been used to a large extent in implementing components which involve limited resources (e.g.. line cards), short time dynamic connections (e.g.. call parties in a call), and generic designs involving subclasses (client server).

When multiple containment is combined with genericity, it is possible to define complex dynamic client server configurations, which appear frequently in real-time designs. Namely, thanks to genericity, it is possible to combine in an equivalence not only actor references of the same class but also actors of compatible classes. This means that by starting with a generic design we can combine it (through equivalences) with other quite specialized designs without having to explicitly define each valid combination of classes. For example, we can define a generic server design in which the various possible clients are all represented as a replicated dynamically substitutable instance of the same abstract class. This design is independent of the actual subclasses that will be inserted at run-time. Whenever we need to link a particular client instance to the server, we can import it in place of any of the generic client "slots" in the server design.

In Developer for C++ or Developer, imported actors are multiply contained actor references that may or may not be present in the current decomposition at any given time during run-time. Unlike static multiply contained actors, an imported actor is not always present in all of its container actors. The actor must be specifically imported into a particular role by the behavior of a higher level actor.

Take for example the following model. It is an example of the use of importation to solve the "limited resource" problem.



 

The resourceManager actor contains the actual instantiated reference to the resource actor(s) as depicted in the following image. Note the two ports on the resource actor. One, resourceIDRequest, is for communication with the ResourceManager to allow the actor to identify itself. The other, resourceInteraction, is used, to communicate with whatever actor it is bound to when imported. This resource actor thus plays multiple roles in the system, but the imported role is played for the duration of the resource use.


 

The applicationA component and the applicationB component both require the use of a limited resource controlled by the resourceManager. Structurally the Application actors look like the following.

 



 

The resource actor is imported into the imported reference and used to perform some activity involving messaging with the application actor. It is then deported and made available to another actor when it requires the resource. The code segment associated with the importation is shown below.

int ret;
resourceId = *RTDATA;
ret = frame.import(resourceId, resource);
if (!ret)
log.log("Severe error - couldn't import resource.");
else {
log.show("Application A using resource.");
log.cr();
resourceInteraction.send(doIt);
}



 

The MSC above gives the interaction scenario between the application actors, resource manager and the resource actor in the C++ application example.

Mimic of importation in Developer for C

Top

The above discussion of the uses and characteristics of importation in the C++ product highlights the severity of the restriction placed upon the C product as a result of not having the frame services available. Even though it is not available in the C product, a close approximation of the import facility can be mimicked in C. Boiled down, the use of importation, as outlined above in the C++ discussion, can be characterized as the dynamic linkage of two actors for the purpose of message exchange, for a limited period of time, with the "imported" actor playing a "role" in the relationship, other than the role it had when instantiated. The C product provides a facility (as does the C++ product) for dynamically registering/de registering SAP/SPP connections. By combining the static linkage of ports between actors and the dynamic linkage of SAPs to SPPs between one of these actors and another which requires it's use for a limited time, the essential characteristics of importation can be achieved using C. In fact, given the nature of SAP/SPP connections and the ability, using the ELS, to connect these across processes, this dynamic linkage can be achieved beyond the standard process boundary of the C++ importation facilities.

Using the same example as given for the C++ Importation case, i.e. a limited resource, required by multiple application level actors, the following model gives the top level view when using the C product and the dynamic SAP/SPP facility to mimic the importation.

 

Note that the major difference with this model, from it's C++ equivalent, is the lack of contained structure in the application actors, and the addition of the timerWindowsNT timer actor which handles timing requests on target for this C model. The ResourceManager actor is very similar since it must handle the requests for and allocation of the resource actor(s) which it contains.

 

The behaviour of the ResourceManager Actor is as follows. Note that it is the same as for the C++ version, except that the protocol for the resourceRequest port contains a signal, requestResource, which passes a RTActorId in the C++ version and an integer value in the C version. The resourceManager starts by querying the resource actors it contains for their "id". In the case of the C product, this is simply an integer value which uniquely identifies the actor. In the example provided, the replication index is used as this value. Once all the resource actors are configured and their reference id known, the resourceManager receives requests for the resource over the resourceRequest port. It responds, if a free resource is available, with the resource id of the free resource. It then marks the resource as in use. If no resource actors are available, an error message is returned to the requester.

 

The resource actor's behaviour is displayed below. This actor receives a message, yourId, from its container. This message contains data indicating the replication index. The resource, in this C example, responds with this integer value as it's reference id and then uses this to form the string version of it's reference id. Note that the string, in the example contains a pre-determined prefix to which the integer value is appended. This forms the unique id which the application actor will have to use and register as well in order for the SAP/SPP connection to be made correctly.

 

The code segment from the yourId transition is as follows, showing the registration of the SPP.

int ret;

/* get my id from the message data */
this->myInstanceId = RECEIVE_SCALAR(int);

/* respond with my id to the requester */
ROOM_PortSendData(resourceIDRequest, myId, SEND_SCALAR(this->myInstanceId) );

/* Now build up the linkName to be used as my registered SPP name. */
sprintf(this->sLinkName, "UseLink%d", this->myInstanceId);

printf("Using SPP named %s\n", this->sLinkName);

/* Now register the SPP name */
ret = ROOM_SPPRegister(useLink, this->sLinkName);
if (!ret)
printf("Severe error - couldn't register resource.\n");
else {
printf("Resource registered.\n");
}



 

In the application actor's behaviour, as displayed above, it can be seen that the actual state machine is the same as in the C++ case. It is only in the code segment related to the handling of the granted signal that the application must do something different from the C++ version. The code segment for the granted signal is displayed below.

int ret;
int nSendAttempts;

this->resourceId = RECEIVE_SCALAR(int);

sprintf(this->sUseLink, "UseLink%d", this->resourceId);
ret = ROOM_SAPRegister(useLink, this->sUseLink);
if (!ret)
printf("Severe error - couldn't import resource.\n");
else {
printf("Application A using resource.\n");
for ( nSendAttempts = 0; nSendAttempts < 5; nSendAttempts++ )
{
if ( !ROOM_PortSend(useLink, doIt) )
{
printf("Error sending message on %s\n", this->sUseLink);
}
else
{
break;
}
}
}
fflush(stdout);


When the actor is finished with the resource, it will release it. In the C++ version, it deports the resource and sends a message to the ResourceManager indicating it is finished with it. In the C version, it deregisters the SAP and then sends the freeResource message to the ResourceManager, as shown below.

if (ROOM_SAPDeRegister(useLink)) {
ROOM_PortSend(resourceRequest, freeResource);

printf("Application A freeing resource.\n");
}
else {
printf("Severe error - cannot deport resource actor.\n");
}



 

The MSC above gives the same scenario as the C++ MSC but using the C version of the product and the dynamic SAP/SPP connections to mimic the use of importation.

Conclusion

As can be seen from this discussion about the example model, the use of dynamically registered/deregistered SAP/SPP connections provides an actor with the ability to play multiple dynamic roles without the actual multiple containment facility being present. Please refer to the provided C++ and C models for the actual details of use.

Limitations:

Top

None.

See also:

Top

ObjecTime 5.2.1 C Guide.
'ImportedResourceC.update - demonstration model for C dynamic role modeling example.
ImportedResourceCPP.update - demonstration model for CPP importation example.