sd-event: split out helper functions for reshuffling prioqs

We typically don't just reshuffle a single prioq at once, but always
two. Let's add two helper functions that do this, and reuse them
everywhere.

(Note that this drops one minor optimization:
sd_event_source_set_time_accuracy() previously only reshuffled the
"latest" prioq, since changing the accuracy has no effect on the
earliest time of an event source, just the latest time an event source
can run. This optimization is removed to simplify things, given that
it's not really worth the effort as prioq_reshuffle() on properly
ordered prioqs has practically zero cost O(1)).

(Slightly generalized, commented and split out of #17284 by Lennart)
This commit is contained in:
Michal Sekletár 2020-10-23 18:29:27 +02:00 committed by Lennart Poettering
parent e08dabfec7
commit e1951c16a8

View file

@ -701,6 +701,33 @@ static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig)
event_unmask_signal_data(e, d, sig);
}
static void event_source_pp_prioq_reshuffle(sd_event_source *s) {
assert(s);
/* Reshuffles the pending + prepare prioqs. Called whenever the dispatch order changes, i.e. when
* they are enabled/disabled or marked pending and such. */
if (s->pending)
prioq_reshuffle(s->event->pending, s, &s->pending_index);
if (s->prepare)
prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
}
static void event_source_time_prioq_reshuffle(sd_event_source *s) {
struct clock_data *d;
assert(s);
assert(EVENT_SOURCE_IS_TIME(s->type));
/* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy,
* pending, enable state. Makes sure the two prioq's are ordered properly again. */
assert_se(d = event_get_clock_data(s->event, s->type));
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
}
static void source_disconnect(sd_event_source *s) {
sd_event *event;
@ -907,16 +934,8 @@ static int source_set_pending(sd_event_source *s, bool b) {
} else
assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
if (EVENT_SOURCE_IS_TIME(s->type)) {
struct clock_data *d;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
}
if (EVENT_SOURCE_IS_TIME(s->type))
event_source_time_prioq_reshuffle(s);
if (s->type == SOURCE_SIGNAL && !b) {
struct signal_data *d;
@ -2207,11 +2226,7 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority)
} else
s->priority = priority;
if (s->pending)
prioq_reshuffle(s->event->pending, s, &s->pending_index);
if (s->prepare)
prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
event_source_pp_prioq_reshuffle(s);
if (s->type == SOURCE_EXIT)
prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
@ -2272,18 +2287,10 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
struct clock_data *d;
case SOURCE_TIME_BOOTTIME_ALARM:
s->enabled = m;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
event_source_time_prioq_reshuffle(s);
break;
}
case SOURCE_SIGNAL:
s->enabled = m;
@ -2342,18 +2349,10 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
struct clock_data *d;
case SOURCE_TIME_BOOTTIME_ALARM:
s->enabled = m;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
event_source_time_prioq_reshuffle(s);
break;
}
case SOURCE_SIGNAL:
@ -2414,11 +2413,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
}
}
if (s->pending)
prioq_reshuffle(s->event->pending, s, &s->pending_index);
if (s->prepare)
prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
event_source_pp_prioq_reshuffle(s);
return 0;
}
@ -2434,7 +2429,6 @@ _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
}
_public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
struct clock_data *d;
int r;
assert_return(s, -EINVAL);
@ -2448,13 +2442,7 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
s->time.next = usec;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
event_source_time_prioq_reshuffle(s);
return 0;
}
@ -2486,7 +2474,6 @@ _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *use
}
_public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
struct clock_data *d;
int r;
assert_return(s, -EINVAL);
@ -2504,12 +2491,7 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec
s->time.accuracy = usec;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
event_source_time_prioq_reshuffle(s);
return 0;
}
@ -2888,9 +2870,7 @@ static int process_timer(
if (r < 0)
return r;
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
event_source_time_prioq_reshuffle(s);
}
return 0;