Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [papyrus-rt-dev] Protocol message parameters with type modifiers

Hi,

Some comments inline below. My conclusions based on this discussion and the apparent confusion it causes, that we really should keep things simple, i.e. we shall not be able to specify any type modifiers to the types of the parameters of a protocol message. From a meta-model perspective a parameter of a protocol message only have a name and a type (which potentially can be unset to indicate the '*' case, see comments below). That's it. This is also what I have proposed that the UI and the tooling shall provide.

No type modifiers like making it into a pointer to the type, no multiplicity and so on. If that is needed, then create a separate class with attributes according to the pattern in legacy models, and have all the expressiveness of the RtCppProperties for how the class and its attributes.

On 6 October 2015 at 17:47, Ernesto Posse <eposse@xxxxxxxxxxxxx> wrote:


On Tue, Oct 6, 2015 at 5:28 AM, Peter Cigéhn <peter.cigehn@xxxxxxxxx> wrote:
Hi,

I saw the Ernesto had submitted https://bugs.eclipse.org/bugs/show_bug.cgi?id=479078 and a proposed Gerrit change https://git.eclipse.org/r/#/c/57454/.

I submitted this because Charles was having an issue in the ComputerSystem model, where he wanted to send a void* and use rtdata on the receiving end.

Okay, but is the intention really to send using a _pointer_ to any data, or it the intention really to send any data (but not necessarily referenced by a pointer)? Without knowing this model in detail and the actual intention, I have strong feeling that this is really is a case that was solved in legacy models to specify '*' as the type for a protocol message. Please note that '*' has nothing to do with pointers, but is similar to a "pattern matching" like the '*' AnyReceiveEvent, i.e. the protocol message can send any data (including not sending any data at all).

I actually checked how this case is handled by Papyrus-RT yesterday, and as a result of that I wrote https://bugs.eclipse.org/bugs/show_bug.cgi?id=479131, since the code-generator cannot handle this case.

In practice what happens when a user selects '*' as a type of protocol message in legacy models is that the parameter is left untyped. See the Bugzilla for more details.

So there is a huge difference to be able to send any kind of data, versus being able to send *a pointer* to any kind of data. I really doubt that this model really has a need to send a pointer to any data. Is the purpose of sending a pointer to avoid the data copying? For performance reasons? For data sharing? How is the data synchronized if its being shared between capsules? How is the data being sent (by a pointer) being allocated? On the heap by the sender? On the stack by the sender (in which case it will not work unless a deep-copy is made)? If it is allocated on the heap by the sender, who ensures that the data de-allocated? Sender? Receiver? When? If the receiver performs a defer and then makes a purge you have a definitive memory leak. There are a multi-tide of things to consider when sending data by reference (and not by value). As I have mentioned before this is an area that I and Andreas have discussed where we have some ideas to annotate the data model to make sure that the code-generator/run-time can ensure that the most efficient sending can be made, e.g. zero-copying (send by reference) if possible, but maybe automatically handle any copying in case if the protocol message is being sent between different memory segments (or possibly using some external communication channel). But this is an area that needs further investigations/discussions/work shops and is not a topic suitable to handle via mail.

 
The issue is related to when you use the RtCppProperties profile to provide "type modifier" to a parameter of a protocol message, e.g. making it a pointer to the specified type.

This is something that is not supported in legacy models, and I am really not sure if, and how, we are going to support this in Papyrus-RT. I actually had a discussion with Remi about this when I showed him how it works when defining protocol messages in legacy tooling. Remi also brought up the aspect of providing multiplicity for a parameter of a protocol message which is not supported either in legacy tooling (well, you can specify multiplicity if you manipulate the low level UML model, but the code generator ignores it).

[epp] In the new RtCppProperties, we allow the user to explicitly specify that the type of a parameter is a pointer. For legacy models, I would expect that the ParameterProperties.type string would be assigned the same raw type string as the corresponding in RSARTE by the import, and then we (the generator) would do a simple parsing of that type, from which we'll detect if it is a pointer and generate the descriptors accordingly. We do not have that parsing yet.

Yes, but keep in mind that the intention of the C++ properties for a parameter is to control how parameters for *ordinary* operations, owned by capsules and classes, are to be generated. The parameters of a protocol message is a different kind of beast and as I have tried to explain, they probably should have a separate set of properties. Keep in mind that in an earlier incarnation of the UML-RT profile, the protocol message was not based on Operations/Call Events, but instead was based on UML Signals/Receptions/SignalEvents. If we still would have had that, then it would have been much more clear that any properties for parameters of protocol messages (since they would be attributes of the signal) would be rather different from parameters to ordinary operations owned by capsules and classes. Bran had to revert using the same approach as in legacy models due to the severe aspects when trying to import/convert legacy models.

And as I have said, I really do not expect *any* legacy models to have pointers specified using the CppPropertySets profiles for parameters of protocol messages, since it is not supported by legacy models. The tooling does not really support it either or actually it has been exposed by "mistake" when the support for multiple parameters partly where introduced in the tooling but not in the code-generator/run-time. But I do not suspect it to be used, since the legacy code-generator ignores them anyway.
 

First of all we need to consider the send-by-value semantics of protocol message sending and the fact that in legacy models protocol messages only had one parameter. Or actually they conceptually had a protocol message which was typed with one single type. The parameter was something that came along with when UML-RT became based on UML 2 and it is only "hidden" internally. In earlier legacy tooling the UML-RT meta-model did not even have a notion of a parameter for a protocol message.

Anyway, back to the send-by-value semantics. When sending a protocol message a copy is made of the data to ensure the send-by-value semantics. For primitive types a simple copy is made, and for the case when the protocol message is typed by a used defined data class, the copy constructor is used to copy the data. And here the aspect of type descriptors come into play.
 
The user then have the possibility of overriding the type descriptor, by for example providing its own copy function body to alter the behavior of the default copy constructor, e.g. if a deep-copy or a shallow-copy (or something in between) shall be made or not. Since the type descriptor information is related to the class itself and also you can override type descriptor and type modifiers for the individual attributes of the class, i.e. it is properties of the RtCppProperties profile and stereotypes applied on the class and its attributes.
 
[epp] FYI, we have some bugs tracking related issues: Bug 471220Bug 475595 and Bug 475596. We had previously discussed that our type descriptors are different and we'll need to adapt them to account for things like numElements.  I'm still working on the implementation of the RtCppProperties.RTSClassifierProperties which allows the user the provide their own copy/encode/decode/init/destroy functions.
  
So traditionally, you have always created a class with attributes to handle more complex types, and you have used the type descriptors for the class and it attributes to control how the copying during the send actually have been performed, e.g. if you want to control if its a shallow or deep copy that is made.

But now we are entering uncharted territory, with the introduction of multiple parameters, and possibly also providing type modifiers already within the scope of the protocol message itself.

To my knowledge, we do not have any type descriptor(s) generated at the scope of a protocol message and its parameters. Yes, there are RtCppProperties related to how parameters for ordinary operations owned by capsules and classes shall be generated in the resulting C++ code.

[epp] Andrew is more familiarized with this, but within the scope of a protocol we are generating a "payload" object for each protocol message. This object is of type UMLRTObject, which contains a size, number of elements and an array of field descriptors, corresponding to each parameter in the message. The field descriptor contains a pointer to the type descriptor which can have its own copy/decode/encode/init/destroy functions.

Okay, I checked the generated code a bit more. So there is "type descriptor" being generated for each protocol message within the scope of the protocol to handle the case with multiple parameters. What I saw was that we also generate a struct with attributes for each of the parameters (which I find fascinating since that is what I proposed could be a solution to solve this in the legacy code-generator!). But this means that we in practice are generating a "class" (in form a struct) for each protocol message, and we generate a "type descriptor" for each such "class". The problem is that we cannot control the code generation of these type descriptors using any RtCppProperties in the way that you are supposed to control the code being generated for user defined classes and its attributes, e.g. override the copy function, i.e. whether a deep-copy or a shallow-copy shall be made.

Yes, you are using the type descriptor for the base type for an individual parameter (which can have its own copy/decode/encode/init/destroy). But since in this case where we talk specifying a pointer to this type, it is not clear if a deep-copy or shallow-copy of the pointer shall be made.
 
 
But the parameters of a protocol message is *not* the same as parameters of an ordinary operation. I would argue that the parameters of protocol message should be much more constrained than the parameters of an ordinary operation, e.g. related to that they cannot have type modifiers, cannot have multiplicity, can only have direction in, and so on. It might be that we lack some constraints in the UML-RT profile to clarify this.

On the other hand, *if* we shall support type modifiers for the parameters of a protocol message, then I have a strong feeling that we need to look into the aspect of type descriptors and ensuring that the end-user can provide its own type descriptor information for the protocol message and its parameters. This would then be another set of properties in the RtCppProperties profile that is only applicable for parameters of a protocol message since they will not make sense for parameters for an ordinary operation.

[epp] Wouldn't such information be given in the type of the parameter rather than the parameter itself, via the RtCppProperties.RTSClassifierProperties stereotype, applied to the parameter's type? 

I think that we are misunderstanding each other here, and I am not sure how to explain this. Yes, in the normal case (as you do in legacy models), such information is always given by the type of the parameter rather than the parameter itself.

But what we are discussing here is that we now apply a "type modifier" on the parameter's type and specifies that it is a pointer to the type. And now we need to be able to specify (within the scope of the protocol message and that specific parameter) how the type modifier is going to be handled, e.g. should the pointer be shallow-copied or deep-copied, how many elements shall be copied in case of that the pointer is actually is an dynamic array of elements and it shall be deep-copied, and so on.

Not sure what I am missing in my explanations. Maybe we need to sort this out in a teleconference?
 
 
Based on this, I would actually propose that we (at least initially) do not support parameters of a protocol message to be typed by anything anything else than a "base type", i.e. either a primitive type or a user defined data class. We shall not support "creating a new type on the fly" by specifying a type modifier saying that the type is a pointer to the specified type (as is the case that Ernesto raises in the Bugzilla and the Gerrit change).

If the user has a need for more complex types, e.g. pointers, arrays and so on, then the pattern used in legacy models is the way to go, i.e. create an additional user defined class with attributes. Then the user can user the RtCppProperties for the class to specify the copy semantics, type modifiers and so on.

Take the following classic example: The user want to send a dynamically sized array of elements. The user then creates data class with two attributes, one indicating the size of the array and attribute which is pointer to the type of elements in the array. For the pointer attribute the user can provide a "numElementsFunctionBody" which basically returns the value of the first attribute. Based on the type descriptor information for this class, a deep copy can now be made where only the current number of elements in the array is copied.

How shall we handle this case if we made these two attributes to be directly as two parameters of the protocol message? How do we ensure that the number of elements to be copied for the second parameter is based on the value of the first parameter? In which "context" can we provide the user a way of defining that?

From a meta-model perspective a protocol message only have a name and a type. Then the specified type's type descriptor is used for the copy operation (avoiding the aspect that a new type is created "on the fly" if we allow type modifiers to be specified for the parameter for which we really do not know and can control how it is being copied).

Any comments?

/Peter Cigéhn

_______________________________________________
papyrus-rt-dev mailing list
papyrus-rt-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/papyrus-rt-dev




--
Ernesto Posse
Zeligsoft.com


_______________________________________________
papyrus-rt-dev mailing list
papyrus-rt-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/papyrus-rt-dev



Back to the top