Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Papyrus for Real Time » Incrementing time
Incrementing time [message #1769802] Thu, 03 August 2017 13:45 Go to next message
reza ahmadi is currently offline reza ahmadiFriend
Messages: 47
Registered: September 2016
Member
I wonder if it is possible to increment time so timers will time out right after that (rather than waiting for a timer to time out normally). Or, for instance, force a timer to timeout, which in such case all other active timers will be naturally affected.

I'll use this for testing purposes as I cannot wait for a timer to normally times out (assume there are many test cases and some timers take a long time to timeout).

I know that a timer port is not externally visible (it's a SAP port), but how such scenarios should be approached?

Thanks.

[Updated on: Thu, 03 August 2017 17:51]

Report message to a moderator

Re: Incrementing time [message #1769816 is a reply to message #1769802] Thu, 03 August 2017 15:52 Go to previous messageGo to next message
Charles Rivet is currently offline Charles RivetFriend
Messages: 219
Registered: May 2014
Location: Canada
Senior Member

The easiest way would be to adjust the clock of the running if that does not adversely affect the rest of your system...
There is a set of operations that allows for adjustment of the system clock, typically to align with a real time clock, that can be used - as long as it does not adversely affect the rest of your system...

To do this, you will need two calls (assuming your timing port is call "timing"):

timing.timeAdjustStart();
// At this point, all timing operations are suspended until the next call
timing.timeAdjustComplete( const UMLRTTimespec & delta );
// where a positive delta moves the clock forward and a negative delta moves it backward.


Another way would be to cancel the timer and then re-create it with a new timeout period - although that would mostly work for timers with single timeouts...

The last way would be to make use of internal APIs...which is not really an intended nor supported way, i.e., there might be unintended consequences...so I would not really recommend it at this point - although you could figure it out by looking at the RTS source...


/Charles Rivet
Re: Incrementing time [message #1769820 is a reply to message #1769802] Thu, 03 August 2017 16:37 Go to previous messageGo to next message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 438
Registered: March 2011
Senior Member
What you are looking for is known as a discrete-event simulator or logical-time simulator. The UML-RT runtime in Papyrus-RT is not such a simulator, it is a real-time runtime. When you schedule a timer, the timeout will be triggered according to the (real) "wall" clock of the underlying platform. Internally, this is implemented in umlrtcontroller.cc, in UMLRTController::wait, which calls "select" (see e.g. http://man7.org/linux/man-pages/man2/select.2.html) with a timeout. Therefore, there is no way to do exactly what you want with the Papyrus-RT runtime.

However, there are some possibilities. To achieve what you want, you have three choices:

1) write your own logical time simulator
2) modify the runtime, in particular the UMLRTController::wait method, and rebuild it
3) use abstraction, defining time values separately from where you start the timers, with small enough time values

I assume that you don't want to spend time writing your own simulator, and modifying the runtime might be quite tricky (you'll need to get deep into how it works), so I suggest the third: use abstraction for your timers, so that whenever you setup a timer, use a variable, symbolic constant or macro which you can configure elsewhere, so that when you run your tests, you set the values to very small amounts.

For example, suppose you have a model with two capsules Capsule1 and Capsule2 both of which have a "timing" port, and in Capsule1 you have the following action in State1:

timing.informIn(UMLRTTimespec(3,0));


and in Capsule2 you have the following action in, say, State1 as well:

timing.informIn(UMLRTTimespec(2,500000000l));


Instead of giving specific values to those timers, define constants for them, either as static read-only attributes in a Class, or as macros defined in an Artifact (or a Class). For example, define a Class called "TimersConfiguration" with static, read-only attributes T1 and T2 of type UMLRTTimespec, and default value set to an OpaqueExpression "UMLRTTimespec(3,0)" and "UMLRTTimespec(2,500000000l)" respectively. Then abstract: replace those actions with

timing.informIn(TimersConfiguration::T1);


and in Capsule2 you have the following action in, say, State1 as well:

timing.informIn(TimersConfiguration::T2);


And create a class diagram with your capsules Capsule1, Capsule2, the TimersConfiguration class and a Dependency relation from Capsule1 to TimersConfiguration and Capsule2 to TimersConfiguration as well.

Then you have separated the timing behaviour of your capsules from the concrete values of your timers, and you only need to configure those timers for your tests.

Recall that the parameters of UMLRTTimespec are seconds (the first) and nanoseconds (the second) and both are of type long. So if you replace those timespecs by small values, say, instead of UMLRTTimespec(3,0), you do UMLRTTimespec(0,3000l), then the timer will be really quick.

An alternative to the TimersConfiguration class, is to define those timers in a header file (an Artifact model element).

In any case, the point is to abstract the concrete values of your timers and put them in some separate element (Class or Artifact) which you can easily configure for your tests with small values.

I'm attaching a sample model that contains examples of both styles. Time values T1 and T2 use the first style (for Capsules 1 and 2), defined in a TimersConfiguration class, and T3 and T4 (capsules 3 and 4) are defined as macros in an Artifact called ExternalTimersConfiguration.

The TimersConfiguration class, also has utilities to obtain a string for a timespec and for the current time, which are useful for logging.


Re: Incrementing time [message #1769823 is a reply to message #1769816] Thu, 03 August 2017 17:07 Go to previous messageGo to next message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 438
Registered: March 2011
Senior Member
The solutions described by Charles work, but the key is this:

Charles Rivet wrote on Thu, 03 August 2017 11:52
[...] if that does not adversely affect the rest of your system...


Using those operations may affect the intended behaviour of your model. The timeAdjustStart method "freezes" the timing service systemwide, so for example, say you have something like a PingPong model with two capsules sending each other messages (Pinger's behaviour is to send ping to Ponger, wait for pong from Ponger and repeat; Ponger's behaviour is to wait for ping; respond with pong and repeat) but they timeout after say 5 seconds that sends them to a "Done" state. So you expect both of them to stop after 5 seconds. If you freeze the timing service with timingAdjustStart, and don't perform timingAdjustComplete, the timers will never fire, the corresponding timeout transitions will never trigger and therefore the two capsules will continue to send each other messages forever, which is a very different behaviour than stopping.

In any case, you have to reason about your model's behaviour to make sure that it is the same with and without timing adjusts. In that case, it might be easier to follow my suggestion to describe a TimersConfiguration separately and use small timing values.



[Updated on: Thu, 03 August 2017 17:10]

Report message to a moderator

Re: Incrementing time [message #1769827 is a reply to message #1769823] Thu, 03 August 2017 18:36 Go to previous messageGo to next message
reza ahmadi is currently offline reza ahmadiFriend
Messages: 47
Registered: September 2016
Member
Thanks Ernesto and Charles!

Ernesto: so, in case of multiple timers in a capsule (or throughout the model), to keep the whole capsule (or model) correct, I would need to divide the actual timer values for all timers throughout the model by a big constant number (to make the actual timer values small) as we want to make the timer values relatively small and at the same time the model should remain correct?

[Updated on: Fri, 04 August 2017 16:17]

Report message to a moderator

Re: Incrementing time [message #1770022 is a reply to message #1769827] Mon, 07 August 2017 14:59 Go to previous message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 438
Registered: March 2011
Senior Member
Yes. If you want guarantee that the behaviour of the system is the same, all delays/timers would have to be divided (or multiplied) by the same amount.

Of course there are cases where it may not matter, as the behaviour might be the same regardless of the timer, but in general, to guarantee the same behaviour, the division would be required.
Previous Topic:Papyrus-rt 0.9 Getting_Started: cannot select protocol for port
Next Topic:User Input
Goto Forum:
  


Current Time: Fri Mar 29 11:22:19 GMT 2024

Powered by FUDForum. Page generated in 0.05034 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top