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