chiark / gitweb /
timer: make timer accuracy configurable
authorLennart Poettering <lennart@poettering.net>
Thu, 21 Nov 2013 21:07:51 +0000 (22:07 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 21 Nov 2013 21:08:20 +0000 (22:08 +0100)
And make it default to 1min

TODO
man/systemd.timer.xml
src/core/dbus-timer.c
src/core/load-fragment-gperf.gperf.m4
src/core/timer.c
src/core/timer.h
units/systemd-readahead-done.timer

diff --git a/TODO b/TODO
index f84a24727b3c76498a551c5102f046d65af4a33d..04d92aba0387a323a839c4a1e8feeb534b59d023 100644 (file)
--- a/TODO
+++ b/TODO
@@ -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)
index 659bc81ccd9d69f2245c6d017b48a6a0687a5d1a..484287ccf67fc3f770f6883e8f7df6039e8b4d3e 100644 (file)
                                 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>
 
                                 <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>
 
                           <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>
 
index 9e4070a1a356a5b78ee38a23d7f41f6d0ccc70a5..b7155219ef52de1026e0c7b62d8e683f63a8fbdc 100644 (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
 };
 
index 22dc536ee19ab1a3566302575255de86a3e669f0..fbf8381bc173745413171b9bc1c883dfe423e89b 100644 (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
index 5bc01a26ff796d23ce7e65514c5e3abafa72af5b..f23582c2db32e0f43d4d3b4f5a3d28665e8dcdd1 100644 (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;
index b3722f0028f325c2e618e864a4916d6dd1a162ef..3e7efa4c8370779fa3bff6423a9a982c74bc497c 100644 (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;
index 41bfb2bd329bb7e9a4efecd2c4a8c60e57304f8d..bdfd4659136d0983f16d9855a3b59d631baafbeb 100644 (file)
@@ -15,6 +15,7 @@ Before=shutdown.target
 
 [Timer]
 OnActiveSec=30s
+AccuracySec=1s
 
 [Install]
 Also=systemd-readahead-collect.service