592caf
From 4ce10f8e41a85a56ad9b805442eb1149ece7c82a Mon Sep 17 00:00:00 2001
592caf
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
592caf
Date: Fri, 23 Oct 2020 18:29:27 +0200
592caf
Subject: [PATCH] sd-event: split out helper functions for reshuffling prioqs
592caf
592caf
We typically don't just reshuffle a single prioq at once, but always
592caf
two. Let's add two helper functions that do this, and reuse them
592caf
everywhere.
592caf
592caf
(Note that this drops one minor optimization:
592caf
sd_event_source_set_time_accuracy() previously only reshuffled the
592caf
"latest" prioq, since changing the accuracy has no effect on the
592caf
earliest time of an event source, just the latest time an event source
592caf
can run. This optimization is removed to simplify things, given that
592caf
it's not really worth the effort as prioq_reshuffle() on properly
592caf
ordered prioqs has practically zero cost O(1)).
592caf
592caf
(Slightly generalized, commented and split out of #17284 by Lennart)
592caf
592caf
(cherry picked from commit e1951c16a8fbe5b0b9ecc08f4f835a806059d28f)
592caf
592caf
Related: #1819868
592caf
---
592caf
 src/libsystemd/sd-event/sd-event.c | 96 ++++++++++++------------------
592caf
 1 file changed, 38 insertions(+), 58 deletions(-)
592caf
592caf
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
592caf
index 0d3bf5cbb6..47f99eb096 100644
592caf
--- a/src/libsystemd/sd-event/sd-event.c
592caf
+++ b/src/libsystemd/sd-event/sd-event.c
592caf
@@ -889,6 +889,33 @@ static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig)
592caf
                 event_unmask_signal_data(e, d, sig);
592caf
 }
592caf
 
592caf
+static void event_source_pp_prioq_reshuffle(sd_event_source *s) {
592caf
+        assert(s);
592caf
+
592caf
+        /* Reshuffles the pending + prepare prioqs. Called whenever the dispatch order changes, i.e. when
592caf
+         * they are enabled/disabled or marked pending and such. */
592caf
+
592caf
+        if (s->pending)
592caf
+                prioq_reshuffle(s->event->pending, s, &s->pending_index);
592caf
+
592caf
+        if (s->prepare)
592caf
+                prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
592caf
+}
592caf
+
592caf
+static void event_source_time_prioq_reshuffle(sd_event_source *s) {
592caf
+        struct clock_data *d;
592caf
+
592caf
+        assert(s);
592caf
+        assert(EVENT_SOURCE_IS_TIME(s->type));
592caf
+
592caf
+        /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy,
592caf
+         * pending, enable state. Makes sure the two prioq's are ordered properly again. */
592caf
+        assert_se(d = event_get_clock_data(s->event, s->type));
592caf
+        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
592caf
+        prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
+        d->needs_rearm = true;
592caf
+}
592caf
+
592caf
 static void source_disconnect(sd_event_source *s) {
592caf
         sd_event *event;
592caf
 
592caf
@@ -1052,16 +1079,8 @@ static int source_set_pending(sd_event_source *s, bool b) {
592caf
         } else
592caf
                 assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
592caf
 
592caf
-        if (EVENT_SOURCE_IS_TIME(s->type)) {
592caf
-                struct clock_data *d;
592caf
-
592caf
-                d = event_get_clock_data(s->event, s->type);
592caf
-                assert(d);
592caf
-
592caf
-                prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
592caf
-                prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
-                d->needs_rearm = true;
592caf
-        }
592caf
+        if (EVENT_SOURCE_IS_TIME(s->type))
592caf
+                event_source_time_prioq_reshuffle(s);
592caf
 
592caf
         if (s->type == SOURCE_SIGNAL && !b) {
592caf
                 struct signal_data *d;
592caf
@@ -2215,11 +2234,7 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority)
592caf
         } else
592caf
                 s->priority = priority;
592caf
 
592caf
-        if (s->pending)
592caf
-                prioq_reshuffle(s->event->pending, s, &s->pending_index);
592caf
-
592caf
-        if (s->prepare)
592caf
-                prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
592caf
+        event_source_pp_prioq_reshuffle(s);
592caf
 
592caf
         if (s->type == SOURCE_EXIT)
592caf
                 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
592caf
@@ -2280,18 +2295,10 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
592caf
                 case SOURCE_TIME_BOOTTIME:
592caf
                 case SOURCE_TIME_MONOTONIC:
592caf
                 case SOURCE_TIME_REALTIME_ALARM:
592caf
-                case SOURCE_TIME_BOOTTIME_ALARM: {
592caf
-                        struct clock_data *d;
592caf
-
592caf
+                case SOURCE_TIME_BOOTTIME_ALARM:
592caf
                         s->enabled = m;
592caf
-                        d = event_get_clock_data(s->event, s->type);
592caf
-                        assert(d);
592caf
-
592caf
-                        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
592caf
-                        prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
-                        d->needs_rearm = true;
592caf
+                        event_source_time_prioq_reshuffle(s);
592caf
                         break;
592caf
-                }
592caf
 
592caf
                 case SOURCE_SIGNAL:
592caf
                         s->enabled = m;
592caf
@@ -2346,18 +2353,10 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
592caf
                 case SOURCE_TIME_BOOTTIME:
592caf
                 case SOURCE_TIME_MONOTONIC:
592caf
                 case SOURCE_TIME_REALTIME_ALARM:
592caf
-                case SOURCE_TIME_BOOTTIME_ALARM: {
592caf
-                        struct clock_data *d;
592caf
-
592caf
+                case SOURCE_TIME_BOOTTIME_ALARM:
592caf
                         s->enabled = m;
592caf
-                        d = event_get_clock_data(s->event, s->type);
592caf
-                        assert(d);
592caf
-
592caf
-                        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
592caf
-                        prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
-                        d->needs_rearm = true;
592caf
+                        event_source_time_prioq_reshuffle(s);
592caf
                         break;
592caf
-                }
592caf
 
592caf
                 case SOURCE_SIGNAL:
592caf
 
592caf
@@ -2405,11 +2404,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
592caf
                 }
592caf
         }
592caf
 
592caf
-        if (s->pending)
592caf
-                prioq_reshuffle(s->event->pending, s, &s->pending_index);
592caf
-
592caf
-        if (s->prepare)
592caf
-                prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
592caf
+        event_source_pp_prioq_reshuffle(s);
592caf
 
592caf
         return 0;
592caf
 }
592caf
@@ -2425,7 +2420,6 @@ _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
592caf
 }
592caf
 
592caf
 _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
592caf
-        struct clock_data *d;
592caf
         int r;
592caf
 
592caf
         assert_return(s, -EINVAL);
592caf
@@ -2439,13 +2433,7 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
592caf
 
592caf
         s->time.next = usec;
592caf
 
592caf
-        d = event_get_clock_data(s->event, s->type);
592caf
-        assert(d);
592caf
-
592caf
-        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
592caf
-        prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
-        d->needs_rearm = true;
592caf
-
592caf
+        event_source_time_prioq_reshuffle(s);
592caf
         return 0;
592caf
 }
592caf
 
592caf
@@ -2460,7 +2448,6 @@ _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *use
592caf
 }
592caf
 
592caf
 _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
592caf
-        struct clock_data *d;
592caf
         int r;
592caf
 
592caf
         assert_return(s, -EINVAL);
592caf
@@ -2478,12 +2465,7 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec
592caf
 
592caf
         s->time.accuracy = usec;
592caf
 
592caf
-        d = event_get_clock_data(s->event, s->type);
592caf
-        assert(d);
592caf
-
592caf
-        prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
-        d->needs_rearm = true;
592caf
-
592caf
+        event_source_time_prioq_reshuffle(s);
592caf
         return 0;
592caf
 }
592caf
 
592caf
@@ -2773,9 +2755,7 @@ static int process_timer(
592caf
                 if (r < 0)
592caf
                         return r;
592caf
 
592caf
-                prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
592caf
-                prioq_reshuffle(d->latest, s, &s->time.latest_index);
592caf
-                d->needs_rearm = true;
592caf
+                event_source_time_prioq_reshuffle(s);
592caf
         }
592caf
 
592caf
         return 0;