summaryrefslogtreecommitdiff
path: root/src/core/job.c
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2019-05-22 12:12:17 +0200
committerMichael Olbrich <m.olbrich@pengutronix.de>2019-07-18 10:28:39 +0200
commitda8e178296f8a34f4156f1e10b8a313de8efee7c (patch)
treeadc765a31ad324b04810d3cccccb1e522eba9729 /src/core/job.c
parentfcfc7e11370f3c0f9f50f6f046b44f7543cf3397 (diff)
downloadsystemd-da8e178296f8a34f4156f1e10b8a313de8efee7c.tar.gz
job: make the run queue order deterministic
Jobs are added to the run queue in random order. This happens because most jobs are added by iterating over the transaction or dependency hash maps. As a result, jobs that can be executed at the same time are started in a different order each time. On small embedded devices this can cause a measurable jitter for the point in time when a job starts (~100ms jitter for 10 units that are started in random order). This results is a similar jitter for the boot time. This is undesirable in general and make optimizing the boot time a lot harder. Also, jobs that should have a higher priority because the unit has a higher CPU weight might get executed later than others. Fix this by turning the job run_queue into a Prioq and sort by the following criteria (use the next if the values are equal): - CPU weight - nice level - unit type - unit name The last one is just there for deterministic sorting to avoid any jitter.
Diffstat (limited to 'src/core/job.c')
-rw-r--r--src/core/job.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/core/job.c b/src/core/job.c
index ced940e093..cda4f344b8 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -7,6 +7,7 @@
#include "alloc-util.h"
#include "async.h"
+#include "cgroup.h"
#include "dbus-job.h"
#include "dbus.h"
#include "escape.h"
@@ -73,7 +74,7 @@ void job_unlink(Job *j) {
assert(!j->object_list);
if (j->in_run_queue) {
- LIST_REMOVE(run_queue, j->manager->run_queue, j);
+ prioq_remove(j->manager->run_queue, j, &j->run_queue_idx);
j->in_run_queue = false;
}
@@ -647,7 +648,7 @@ int job_run_and_invalidate(Job *j) {
assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
assert(j->in_run_queue);
- LIST_REMOVE(run_queue, j->manager->run_queue, j);
+ prioq_remove(j->manager->run_queue, j, &j->run_queue_idx);
j->in_run_queue = false;
if (j->state != JOB_WAITING)
@@ -1146,13 +1147,13 @@ void job_add_to_run_queue(Job *j) {
if (j->in_run_queue)
return;
- if (!j->manager->run_queue) {
+ if (prioq_isempty(j->manager->run_queue)) {
r = sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT);
if (r < 0)
log_warning_errno(r, "Failed to enable job run queue event source, ignoring: %m");
}
- LIST_PREPEND(run_queue, j->manager->run_queue, j);
+ prioq_put(j->manager->run_queue, j, &j->run_queue_idx);
j->in_run_queue = true;
}