mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
timer: make timer accuracy configurable
And make it default to 1min
This commit is contained in:
parent
b850b06e1e
commit
9f5eb56a13
2
TODO
2
TODO
@ -466,8 +466,6 @@ Features:
|
|||||||
* deal with sendmail/postfix exclusivity
|
* deal with sendmail/postfix exclusivity
|
||||||
|
|
||||||
* timer units:
|
* 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 events with system resume
|
||||||
- timer units should get the ability to trigger when:
|
- timer units should get the ability to trigger when:
|
||||||
o CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)
|
o CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)
|
||||||
|
@ -163,7 +163,14 @@
|
|||||||
to any of these options, the list of
|
to any of these options, the list of
|
||||||
timers is reset, and all prior
|
timers is reset, and all prior
|
||||||
assignments will have no
|
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>
|
</varlistentry>
|
||||||
|
|
||||||
@ -171,16 +178,61 @@
|
|||||||
<term><varname>OnCalendar=</varname></term>
|
<term><varname>OnCalendar=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Defines realtime
|
<listitem><para>Defines realtime
|
||||||
(i.e. wallclock) timers via calendar
|
(i.e. wallclock) timers with calendar
|
||||||
event expressions. See
|
event expressions. See
|
||||||
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
for more information on the syntax of
|
for more information on the syntax of
|
||||||
calendar event expressions. Otherwise
|
calendar event expressions. Otherwise
|
||||||
the semantics are similar to
|
the semantics are similar to
|
||||||
<varname>OnActiveSec=</varname> and
|
<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>
|
||||||
|
|
||||||
|
<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>
|
<varlistentry>
|
||||||
<term><varname>Unit=</varname></term>
|
<term><varname>Unit=</varname></term>
|
||||||
|
|
||||||
@ -208,7 +260,9 @@
|
|||||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd.service</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.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>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -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("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("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("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
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -247,6 +247,7 @@ Timer.OnBootSec, config_parse_timer, 0,
|
|||||||
Timer.OnStartupSec, config_parse_timer, 0, 0
|
Timer.OnStartupSec, config_parse_timer, 0, 0
|
||||||
Timer.OnUnitActiveSec, config_parse_timer, 0, 0
|
Timer.OnUnitActiveSec, config_parse_timer, 0, 0
|
||||||
Timer.OnUnitInactiveSec, 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
|
Timer.Unit, config_parse_trigger_unit, 0, 0
|
||||||
m4_dnl
|
m4_dnl
|
||||||
Path.PathExists, config_parse_path_spec, 0, 0
|
Path.PathExists, config_parse_path_spec, 0, 0
|
||||||
|
@ -47,6 +47,7 @@ static void timer_init(Unit *u) {
|
|||||||
|
|
||||||
t->next_elapse_monotonic = (usec_t) -1;
|
t->next_elapse_monotonic = (usec_t) -1;
|
||||||
t->next_elapse_realtime = (usec_t) -1;
|
t->next_elapse_realtime = (usec_t) -1;
|
||||||
|
t->accuracy_usec = USEC_PER_MINUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_free_values(Timer *t) {
|
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) {
|
static void timer_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
|
char buf[FORMAT_TIMESPAN_MAX];
|
||||||
Timer *t = TIMER(u);
|
Timer *t = TIMER(u);
|
||||||
Unit *trigger;
|
Unit *trigger;
|
||||||
TimerValue *v;
|
TimerValue *v;
|
||||||
@ -153,10 +155,12 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
|
|||||||
fprintf(f,
|
fprintf(f,
|
||||||
"%sTimer State: %s\n"
|
"%sTimer State: %s\n"
|
||||||
"%sResult: %s\n"
|
"%sResult: %s\n"
|
||||||
"%sUnit: %s\n",
|
"%sUnit: %s\n"
|
||||||
|
"%sAccuracy: %s\n",
|
||||||
prefix, timer_state_to_string(t->state),
|
prefix, timer_state_to_string(t->state),
|
||||||
prefix, timer_result_to_string(t->result),
|
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) {
|
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);
|
r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_ONESHOT);
|
||||||
} else
|
} 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)
|
if (r < 0)
|
||||||
goto fail;
|
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);
|
r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_ONESHOT);
|
||||||
} else
|
} 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)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -69,6 +69,8 @@ typedef enum TimerResult {
|
|||||||
struct Timer {
|
struct Timer {
|
||||||
Unit meta;
|
Unit meta;
|
||||||
|
|
||||||
|
usec_t accuracy_usec;
|
||||||
|
|
||||||
LIST_HEAD(TimerValue, values);
|
LIST_HEAD(TimerValue, values);
|
||||||
usec_t next_elapse_monotonic;
|
usec_t next_elapse_monotonic;
|
||||||
usec_t next_elapse_realtime;
|
usec_t next_elapse_realtime;
|
||||||
|
@ -15,6 +15,7 @@ Before=shutdown.target
|
|||||||
|
|
||||||
[Timer]
|
[Timer]
|
||||||
OnActiveSec=30s
|
OnActiveSec=30s
|
||||||
|
AccuracySec=1s
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
Also=systemd-readahead-collect.service
|
Also=systemd-readahead-collect.service
|
||||||
|
Loading…
Reference in New Issue
Block a user