summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuri Lelli <juri.lelli@arm.com>2016-11-22 12:29:27 +0000
committerJuri Lelli <juri.lelli@arm.com>2016-11-25 08:21:18 +0000
commit50e9a5123e65e77cd4aeca4c8b0eded16579bb14 (patch)
treeda22535274a1cc1747aac7bdb5c2cb5f1f0ee16e
parent74820a3998053e424e9f198d8770f10fa30b32ce (diff)
rt-app: implement relative/absolute timers
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>
-rw-r--r--doc/tutorial.txt64
-rw-r--r--src/rt-app.c3
-rw-r--r--src/rt-app_parse_config.c6
-rw-r--r--src/rt-app_types.h1
4 files changed, 73 insertions, 1 deletions
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
index dfcc405..a4455b6 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 2627d58..fb4b37d 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 b0f302e..fbc4612 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 8998320..718ce77 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 {