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