diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | man/systemd.timer.xml | 62 | ||||
-rw-r--r-- | src/core/dbus-timer.c | 1 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 1 | ||||
-rw-r--r-- | src/core/timer.c | 12 | ||||
-rw-r--r-- | src/core/timer.h | 2 | ||||
-rw-r--r-- | units/systemd-readahead-done.timer | 1 |
7 files changed, 71 insertions, 10 deletions
@@ -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) diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml index 659bc81ccd..484287ccf6 100644 --- a/man/systemd.timer.xml +++ b/man/systemd.timer.xml @@ -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,17 +178,62 @@ <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> <listitem><para>The unit to activate @@ -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> diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index 9e4070a1a3..b7155219ef 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -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 }; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 22dc536ee1..fbf8381bc1 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -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 diff --git a/src/core/timer.c b/src/core/timer.c index 5bc01a26ff..f23582c2db 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -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; diff --git a/src/core/timer.h b/src/core/timer.h index b3722f0028..3e7efa4c83 100644 --- a/src/core/timer.h +++ b/src/core/timer.h @@ -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; diff --git a/units/systemd-readahead-done.timer b/units/systemd-readahead-done.timer index 41bfb2bd32..bdfd465913 100644 --- a/units/systemd-readahead-done.timer +++ b/units/systemd-readahead-done.timer @@ -15,6 +15,7 @@ Before=shutdown.target [Timer] OnActiveSec=30s +AccuracySec=1s [Install] Also=systemd-readahead-collect.service |