On 24 November 2016 at 11:32, Juri Lelli juri.lelli@arm.com wrote:
Implement "relative" (current behavior) and "absolute" working modes for timer events. Text added in doc/tutorial.txt gives more information about the two modes.
Signed-off-by: Juri Lelli juri.lelli@arm.com
Acked-by: Vincent Guittot vincent.guittot@linaro.org
doc/tutorial.txt | 64 +++++++++++++++++++++++++++++++++++++++++++++++ src/rt-app.c | 3 ++- src/rt-app_parse_config.c | 6 +++++ src/rt-app_types.h | 1 + 4 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/doc/tutorial.txt b/doc/tutorial.txt index dfcc40567729..a4455b601cd3 100644 --- a/doc/tutorial.txt +++ b/doc/tutorial.txt @@ -321,6 +321,70 @@ below: } }
+Timers can work with a "relative" or an "absolute" reference. By default they +work in "relative" mode, but this mode can also be explicity specified as the +following:
"phases" : {
"phase0" : {
"loop" : 10,
"run0" : 10000,
"timer0" : { "ref" : "unique", "period" : 20000, "mode" : "relative" },
}
+"relative" mode means that the reference for setting the next timer event is +relative to the end of the current phase. This in turn means that if, for some +reason (i.e., clock frequency was too low), events in a certain phase took too +long to execute and the timer of that phase couldn't actually fire at all, the +next phase won't be affected. For example:
- +---- + +-----+ +-------------------+-----+ +---
- |r0 | |r0 | |r0 |r0 | |r0
- | | | | | | | |
- o-----------o-----------o-------------------o-----------o------->
- 0 10 20 30 40 50 60 70 80 100 120
^ ^ ^ ^
| | | MISS! |
+ + + +
Timer0 Timer0 Timer0 Timer0
+In this example character "o" denotes when phases finish/start. Third +activation of Timer0 is missed, since r0 executed for more that 20ms. However +the next phase is not affected as Timer0 was set considering the instant of +time when the misbehaving r0 finished executing.
+"absolute" mode is specified as the following:
"phases" : {
"phase0" : {
"loop" : 10,
"run0" : 10000,
"timer0" : { "ref" : "unique", "period" : 20000, "mode" : "absolute" },
}
+"absolute" mode means that the reference for setting the next timer event is +fixed and always consider the starting time of the first phase. This means that +if, for some reason (i.e., clock frequency was too low), events in a certain +phase took too long to execute and the timer of that phase couldn't actually +fire at all, the next phase (and potentially other subsequent phases) _will_ be +affected. For example, considering again the example above:
- +---- + +-----+ +-------------------+-----+-----+ +---
- |r0 | |r0 | |r0 |r0 |r0 | |r0
- | | | | | | | | |
- o-----------o-----------o-------------------o-----o---------o---->
- 0 10 20 30 40 50 60 70 80 100 120
^ ^ ^ ^ ^
| | | MISS! | MISS! |
+ + + + +
Timer0 Timer0 Timer0 Timer0 Timer0
+Third activation of Timer0 is missed, since r0 executed for more that 20ms. +Even if 4th activation of r0 executes for 10ms (as specified in the +configuration), 4th Timer0 is still missed because the reference didn't change. +In this example 5th activation of r0 then managed to recover, but in general it +depends on how badly a certain phase misbehaves.
lock : String. Lock the mutex defined by the string value.
unlock : String. Unlock the mutex defined by the string value.
diff --git a/src/rt-app.c b/src/rt-app.c index 93282e0a068c..5b67a935397f 100644 --- a/src/rt-app.c +++ b/src/rt-app.c @@ -339,7 +339,8 @@ static int run_event(event_data_t *event, int dry_run, t_wu = timespec_sub(&t_now, &rdata->res.timer.t_next); ldata->wu_latency = timespec_to_usec(&t_wu); } else {
clock_gettime(CLOCK_MONOTONIC, &rdata->res.timer.t_next);
if (rdata->res.timer.relative)
clock_gettime(CLOCK_MONOTONIC, &rdata->res.timer.t_next); ldata->wu_latency = 0UL; } }
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c index b0f302e2ba25..fbc4612b2257 100644 --- a/src/rt-app_parse_config.c +++ b/src/rt-app_parse_config.c @@ -181,6 +181,7 @@ static int init_timer_resource(rtapp_resource_t *data, const rtapp_options_t *op { log_info(PIN3 "Init: %s timer", data->name); data->res.timer.init = 0;
data->res.timer.relative = 1;
}
static int init_cond_resource(rtapp_resource_t *data, const rtapp_options_t *opts) @@ -489,6 +490,11 @@ parse_thread_event_data(char *name, struct json_object *obj, rdata = &(opts->resources[data->res]); ddata = &(opts->resources[data->dep]);
tmp = get_string_value_from(obj, "mode", TRUE, "relative");
if (!strncmp(tmp, "absolute", strlen("absolute")))
rdata->res.timer.relative = 0;
free(tmp);
log_info(PIN2 "type %d target %s [%d] period %d", data->type, rdata->name, rdata->index, data->duration); return; }
diff --git a/src/rt-app_types.h b/src/rt-app_types.h index 89983203f479..718ce7798cc2 100644 --- a/src/rt-app_types.h +++ b/src/rt-app_types.h @@ -87,6 +87,7 @@ struct _rtapp_signal { struct _rtapp_timer { struct timespec t_next; int init;
int relative;
};
struct _rtapp_iomem_buf {
2.10.0