Home » Eclipse Projects » Papyrus for Real Time » Understanding the behaviour of the code generator
|Understanding the behaviour of the code generator [message #1775750]
|Sun, 05 November 2017 13:52
| Nicolas Hili
Registered: March 2017
I ran into a weird behaviour and would like to know whether it is the expected one or not.
Let's assume that I have a capsule C with two ports a of type A and b of type B. A is a protocol defining an incoming message foo and B is a protocol defining an incoming message bar.
Secondly, let's assume that I have in the state machine of C a state s1 in such a way that two different transitions have s1 as target state. The first transition is fired upon reception of foo (from port a:A) and the second is fired upon reception of bar (from port b:B).
If I generate code from that model, I will be able to enter s1 whenever I receive foo or bar (assuming that I am waiting into a state s0 that is the source state of the two transitions). The code generates, compiles, and the program can be executed.
Finally, let's assume that foo and bar (resp.) contain each a parameter fooParam and barParam (resp.) of same type (e.g., both are integers). When generating the code, I can see in the entry action of s1 that only a constant for the first param (barParam) has been defined:
#define fooParam ( *(int *)msg->getParam ( 0 ) )
That means that I cannot use barParam in the entry action of s1. However, interestingly, the fooParam constant will have the value of fooParam (upon reception of a:A) or the value of barParam (upon reception of b:B) depending on which of the two messages is received. So in the specific scenario where both fooParam and barParam are of same type, I can only use fooParam in the entry action code of s1 but I will be able to get the value of each parameter. However, things get confused if both parameters are of different types (e.g., int and float). It seems that in that case, the code generator behaves the same and it will only consider the first parameter and not the second one. So, when receiving b:B (that contains a float parameter), the fooParam constant in the entry action of s1 will be cast into integer which results in an incorrect output.
I am assuming that having two different transitions with the same target state and fired upon reception of messages from different protocols (and with different parameters) is a bad design, but I am curious about understanding what is the correct behaviour of the code generator in that case.
Thanks a lot,
|Re: Understanding the behaviour of the code generator [message #1775779 is a reply to message #1775750]
|Mon, 06 November 2017 09:42
| Peter Cigehn
Registered: September 2014
Ernesto can probably provide a more elaborate answer, but to me this feels like a flaw in the code-generator.
What we should keep in mind is that the support for multiple, and explicitly named, parameters in protocol message is new in Papyrus-RT compared to legacy tooling and code-generators for UML-RT. Legacy code-generators supported only one parameter with a hard-coded name, i.e. rtdata (a legacy which can be spotted in Papyrus-RT as well with the generation of the rtdata macro).
When passing multiple "parameters" you had to create a separate data class with multiple attributes and type the single parameter with this data class. So considering how new the support for multiple parameters are, there are probably cases like this which have not been fully considered.
If I compare with the legacy code generator, the generated entry action code does not even provide direct access to the parameter. So the code-generator in Papyrus-RT maybe should do the same to avoid ambiguities like this, or at least try to handle it in a better way, e.g. to only generate access to the "anonymous" rtdata parameter, possibly only provide a void pointer in the case when the (single) parameter is typed differently for the incoming transitions.
As you say, letting the entry action code handle, differently named and possibly differently typed, parameters from multiple incoming transitions is probably not a good design. The parameters are better handled by the effect code on the incoming transitions themselves.
|Re: Understanding the behaviour of the code generator [message #1775806 is a reply to message #1775779]
|Mon, 06 November 2017 17:16
| Ernesto Posse
Registered: March 2011
Hi. You have run into a bug. Indeed, as Peter said, it is a case we had not considered.
The reason why the generator produces such code is this: during code generation of state machines we "flatten" the state machine. During this process, for each state, we "move out" the state's entry action to each of the state's incoming transitions. More precisely, we create references to the entry action, so the transition ends up with a chain of actions to execute and the reference to the entry action is the last in the chain. This is so that the rest of the code generator can deal with only one case: actions on transitions, rather than having to deal with transition actions, entry actions and exit actions separately. Anyway, let's call en_s1 the entry action of s1. So at this point you have two transitions t1 and t2, and both of which have (a reference to) en_s1 as their last action in the chain. Then the generator goes through all transition action chains and generates code for each action in the chain. So when it is generating the actions in t1's chain, it generates code for en_s1 using t1's parameters ("fooParam"). The generated functions are cached. For each transition we also generate an "action chain" function which calls all the actions in the chain. When the generator moves to t2, it finds that the function for its last action en_s1 was already generated (because it was cached) and skips it, but its action chain function will correctly have a call to the function for en_s1. As a result, you end up with only one entry action function for s1 (as expected) but it only has the macro for the parameter of the first incoming transition that was visited by the generator.
I think we should be generating macros for all parameters of all incoming transitions on a state's entry action. This might lead to user errors though, for example if you arrive at s1 via the bar transition and tried to obtain fooParam. There are possible patterns of macros that we could generate in such cases, but when I proposed a macro pattern to deal with multiple parameters that took into account the protocol message, it was rejected. Maybe now the project leads would be more open to a more accurate macro pattern now that we are less tied to the legacy.
In any case, could you open a bug for it? Thanks.
|Re: Understanding the behaviour of the code generator [message #1775814 is a reply to message #1775806]
|Mon, 06 November 2017 18:05
| Nicolas Hili
Registered: March 2017
Hello Peter, Ernesto,
Thanks for your replies. Indeed, if the entry action code en_s1 is cached, that makes sense that only the macro for the first message fooParam has been generated.
I do agree with Peter, generating macros for each parameter rather than the only rtdata one is a huge step forward compared to other code generators. Maybe in that case, patterns of macros mentioned by Ernesto is a good approach. I guess to make it simple, instead of having an ordered list of parameter, a dictionary would work, is not it?
@Ernesto: I will prepare a UML-RT model and open a bug.
Current Time: Thu Feb 29 18:47:31 GMT 2024
Powered by FUDForum
. Page generated in 0.08408 seconds