To explain several strategies for managing data with the ObjecTime Developer for C product. This is specifically aimed at the use of this data in messages between actors.
Modelers using data in messages between actors in ObjecTime Developer for C.
A pattern for message allocation which can be used with the OTD for C product is required since any data passed between actors must
be passed as either a scalar value or a pointer to a structure. This is not inherently an ObjecTime Developer for C problem as these data management issues arise in general application developer without ObjecTime Developer for C. The following are situations in which such a pattern is required.
1. Many C projects have mandates that dynamic memory cannot be allocated once the application is running.
2. In the C product, when sending complex data, an external data structure must be defined. The typical scenario under which this
data is used is as follows.
a. An instance of this structure, often an Extended State Variable (ESV) on an actor, is used to store the data.
This actor then sends a pointer to this data, in a message using the SEND_SCALAR() macro to wrap this pointer.
b. The receiving actor gets the signal in a transition and accepts the data pointer by calling RECEIVE_SCALAR(
Note that in the simple scenario described above, the sender does not have any idea when the receiver has processed the data
and could end up writing into the data structure before the receiver has received and finished with the data.
3. The scenario described in (2) above can be changed such that the sender always allocates an element of the desired
type from the heap, and sends this pointer to the receiver. The sender is then unconcerned with the pointer to the structure.
The receiver receives the pointer and is responsible for freeing the memory after using the data.
This passing of ownership of the data is a good practice, when using the ObjecTime Developer for C product, but is still prone to problems in the form of
potential memory leaks, if the receiver fails to free the memory.
The modeling technique described demonstrates the use of a DataManager to actually maintain the data structures required by other
actors for their messaging. It addresses the issues in the presented scenarios, but still relies to some extent on an application
level protocol to control the access to the required data structures.
Design:
A DataManager actor is responsible for the allocation and handling of data structures. Any actor (Sender) which needs to use a data
structure sends a request to the DataManager actor to gain access to a structure. The DataManger checks for an available structure,
sends back an acknowledgement with a pointer to the structure. Note that the DataManager marks this structure as in use until it is
released. The using actor (Sender) stuffs the structure, makes use of it, and sends the pointer to the structure to another actor
(Receiver) in a message. By sending the structure in a message to the other actor, Sender effectively gives up the control of the
structure. Receiver gains control of the particular structure and can use it as required. When finally finished with the structure,
the last actor using it sends a Release request to the DataManager to free up the structure for use by another actor.
Note that the pointer mentioned above can be either an actual pointer to the data structure, if stored locally within the DataManager,
or an integer index if using a globally accessible array of structure elements.
The following Message Sequence Chart depicts the interaction described above.
Limitations:
The method described and used in the example models relies on an application level protocol whereby the actor using a data structure,
once it has sent a pointer to it in a message, relinquishes control and access to that structure. If this actor used the structure after
passing it on, it could cause a race condition on the access of the data, competing with the receiver of the message for the access. As
well, this method relies on some actor, down the receiving chain, to free the structure for future use by informing the DataManager that
the structure is no longer required.
The method presented in the MessageDataMgmtWithCPtr.update is perhaps a better implementation, from an OO perspective since it hides
the details of how the data structures are allocated and stored within the DataManager actor. The MessageDataMgmtWithCGlobal.update
presents a method in which the data is in a global array. This is potentially a faster implementation but prone to the problems of
using global data.
ObjecTime 5.2.1 C Guide.
MessageDataMgmtWithCPtr.update - demonstration model for pointer method.
MessageDataMgmtWithCGlobal.update - demonstration model for global method.