timer: make timer accuracy configurable

And make it default to 1min
This commit is contained in:
Lennart Poettering 2013-11-21 22:07:51 +01:00
parent b850b06e1e
commit 9f5eb56a13
7 changed files with 71 additions and 10 deletions

2
TODO
View File

@ -466,8 +466,6 @@ Features:
* deal with sendmail/postfix exclusivity
* timer units:
- configurable jitter for timer events
- Adjust timers to be triggered at the same time as sd-event timers
- timer events with system resume
- timer units should get the ability to trigger when:
o CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)

View File

@ -163,7 +163,14 @@
to any of these options, the list of
timers is reset, and all prior
assignments will have no
effect.</para></listitem>
effect.</para>
<para>Note that timers are not
necessarily expired at the precise
time configured with these settings,
as they are subject to the
<varname>AccuracySec=</varname>
setting below.</para></listitem>
</varlistentry>
@ -171,16 +178,61 @@
<term><varname>OnCalendar=</varname></term>
<listitem><para>Defines realtime
(i.e. wallclock) timers via calendar
(i.e. wallclock) timers with calendar
event expressions. See
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for more information on the syntax of
calendar event expressions. Otherwise
the semantics are similar to
<varname>OnActiveSec=</varname> and
related settings.</para></listitem>
related settings.</para>
<para>Note that timers are not
necessarily expired at the precise
time configured with this setting,
as it is subject to the
<varname>AccuracySec=</varname>
setting below.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>AccuracySec=</varname></term>
<listitem><para>Specify the accuracy
the timer shall elapse with. Defaults
to 1min. The timer is scheduled to
expire within a time window starting
with the time specified in
<varname>OnCalendar=</varname>,
<varname>OnActiveSec=</varname>,
<varname>OnBootSec=</varname>,
<varname>OnStartupSec=</varname>,
<varname>OnUnitActiveSec=</varname> or
<varname>OnUnitInactiveSec=</varname>
and ending the time configured with
<varname>AccuracySec=</varname>
later. Within this time window the
expiry time will be placed at a
host-specific, randomized but stable
position, that is synchronized between
all local timer units. This is done in
order to distribute the wake-up time
in networked installations, as well as
optimizing power consumption to
suppress unnecessary CPU wake-ups. To
get best accuracy set this option to
1us. Note that the timer is still
subject to the timer slack configured
via
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>'s
<varname>TimerSlackNSec=</varname>
setting. See
<citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
for details. To optimize power
consumption make sure to set this
value as high as possible and as low
as necessary.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Unit=</varname></term>
@ -208,7 +260,9 @@
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -143,6 +143,7 @@ const sd_bus_vtable bus_timer_vtable[] = {
SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_monotonic), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), 0),
SD_BUS_VTABLE_END
};

View File

@ -247,6 +247,7 @@ Timer.OnBootSec, config_parse_timer, 0,
Timer.OnStartupSec, config_parse_timer, 0, 0
Timer.OnUnitActiveSec, config_parse_timer, 0, 0
Timer.OnUnitInactiveSec, config_parse_timer, 0, 0
Timer.AccuracySec, config_parse_sec, 0, offsetof(Timer, accuracy_usec)
Timer.Unit, config_parse_trigger_unit, 0, 0
m4_dnl
Path.PathExists, config_parse_path_spec, 0, 0

View File

@ -47,6 +47,7 @@ static void timer_init(Unit *u) {
t->next_elapse_monotonic = (usec_t) -1;
t->next_elapse_realtime = (usec_t) -1;
t->accuracy_usec = USEC_PER_MINUTE;
}
void timer_free_values(Timer *t) {
@ -144,6 +145,7 @@ static int timer_load(Unit *u) {
}
static void timer_dump(Unit *u, FILE *f, const char *prefix) {
char buf[FORMAT_TIMESPAN_MAX];
Timer *t = TIMER(u);
Unit *trigger;
TimerValue *v;
@ -153,10 +155,12 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f,
"%sTimer State: %s\n"
"%sResult: %s\n"
"%sUnit: %s\n",
"%sUnit: %s\n"
"%sAccuracy: %s\n",
prefix, timer_state_to_string(t->state),
prefix, timer_result_to_string(t->result),
prefix, trigger ? trigger->id : "n/a");
prefix, trigger ? trigger->id : "n/a",
prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1));
LIST_FOREACH(value, v, t->values) {
@ -346,7 +350,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_ONESHOT);
} else
r = sd_event_add_monotonic(UNIT(t)->manager->event, t->next_elapse_monotonic, 0, timer_dispatch, t, &t->monotonic_event_source);
r = sd_event_add_monotonic(UNIT(t)->manager->event, t->next_elapse_monotonic, t->accuracy_usec, timer_dispatch, t, &t->monotonic_event_source);
if (r < 0)
goto fail;
@ -372,7 +376,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_ONESHOT);
} else
r = sd_event_add_realtime(UNIT(t)->manager->event, t->next_elapse_realtime, 0, timer_dispatch, t, &t->realtime_event_source);
r = sd_event_add_realtime(UNIT(t)->manager->event, t->next_elapse_realtime, t->accuracy_usec, timer_dispatch, t, &t->realtime_event_source);
if (r < 0)
goto fail;

View File

@ -69,6 +69,8 @@ typedef enum TimerResult {
struct Timer {
Unit meta;
usec_t accuracy_usec;
LIST_HEAD(TimerValue, values);
usec_t next_elapse_monotonic;
usec_t next_elapse_realtime;

View File

@ -15,6 +15,7 @@ Before=shutdown.target
[Timer]
OnActiveSec=30s
AccuracySec=1s
[Install]
Also=systemd-readahead-collect.service