From 850516e012f0e2c96cecb63c1e8997e13912fcd6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 21 Nov 2013 00:46:13 +0100 Subject: [PATCH] sd-event: try to move timer wakeups to the same spot within each minute --- TODO | 2 -- src/libsystemd-bus/sd-event.c | 32 ++++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 21996eae90d..454d283b4e4 100644 --- a/TODO +++ b/TODO @@ -49,8 +49,6 @@ Features: * timer: expose accuracy as unit setting -* sd-event: do per-minute coalescing of timer events too - * when we detect low battery and no AC on boot, show pretty splash and refuse boot * move libasyncns into systemd as libsystemd-asyncns diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c index 2dc36721426..2a8eac6df2f 100644 --- a/src/libsystemd-bus/sd-event.c +++ b/src/libsystemd-bus/sd-event.c @@ -640,15 +640,16 @@ static int event_setup_timer_fd( } /* When we sleep for longer, we try to realign the wakeup to - the same time wihtin each second, so that events all across - the system can be coalesced into a single CPU - wakeup. However, let's take some system-specific randomness - for this value, so that in a network of systems with synced - clocks timer events are distributed a bit. Here, we - calculate a perturbation usec offset from the boot ID. */ + the same time wihtin each minute/second/250ms, so that + events all across the system can be coalesced into a single + CPU wakeup. However, let's take some system-specific + randomness for this value, so that in a network of systems + with synced clocks timer events are distributed a + bit. Here, we calculate a perturbation usec offset from the + boot ID. */ if (sd_id128_get_boot(&bootid) >= 0) - e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_SEC; + e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE; *timer_fd = fd; return 0; @@ -1363,13 +1364,24 @@ static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) { dispatch as much as possible on the entire system. We implement this by waking up everywhere at the same time - within any given second if we can, synchronised via the + within any given minute if we can, synchronised via the perturbation value determined from the boot ID. If we can't, - then we try to find the same spot in every a 250ms + then we try to find the same spot in every 1s and then 250ms step. Otherwise, we pick the last possible time to wake up. */ - c = (b / USEC_PER_SEC) * USEC_PER_SEC + e->perturb; + c = (b / USEC_PER_MINUTE) * USEC_PER_MINUTE + e->perturb; + if (c >= b) { + if (_unlikely_(c < USEC_PER_MINUTE)) + return b; + + c -= USEC_PER_MINUTE; + } + + if (c >= a) + return c; + + c = (b / USEC_PER_SEC) * USEC_PER_SEC + (e->perturb % USEC_PER_SEC); if (c >= b) { if (_unlikely_(c < USEC_PER_SEC)) return b;