|
|
1abbee |
From 33ca0f1f0d4b9a91588c84067d2fb30968e41235 Mon Sep 17 00:00:00 2001
|
|
|
a4d3ef |
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= <lnykryn@redhat.com>
|
|
|
a4d3ef |
Date: Tue, 14 Jun 2016 14:20:56 +0200
|
|
|
a4d3ef |
Subject: [PATCH] manager: reduce complexity of unit_gc_sweep (#3507)
|
|
|
a4d3ef |
|
|
|
a4d3ef |
When unit is marked as UNSURE, we are trying to find if it state was
|
|
|
a4d3ef |
changed over and over again. So lets not go through the UNSURE states
|
|
|
a4d3ef |
again. Also when we find a GOOD unit lets propagate the GOOD state to
|
|
|
a4d3ef |
all units that this unit reference.
|
|
|
a4d3ef |
|
|
|
a4d3ef |
This is a problem on machines with a lot of initscripts with different
|
|
|
a4d3ef |
starting priority, since those units will reference each other and the
|
|
|
a4d3ef |
original algorithm might get to n! complexity.
|
|
|
a4d3ef |
|
|
|
a4d3ef |
Thanks HATAYAMA Daisuke for the expand_good_state code.
|
|
|
a4d3ef |
Cherry-picked from: 4892084f096c19da0e83f28f250ca187b58c22b2
|
|
|
a4d3ef |
Resolves: #1344556
|
|
|
a4d3ef |
---
|
|
|
a4d3ef |
src/core/manager.c | 16 +++++++++++++++-
|
|
|
a4d3ef |
1 file changed, 15 insertions(+), 1 deletion(-)
|
|
|
a4d3ef |
|
|
|
a4d3ef |
diff --git a/src/core/manager.c b/src/core/manager.c
|
|
|
c62b8e |
index 370c8cbbed..e5226a8a6f 100644
|
|
|
a4d3ef |
--- a/src/core/manager.c
|
|
|
a4d3ef |
+++ b/src/core/manager.c
|
|
|
1abbee |
@@ -838,6 +838,19 @@ enum {
|
|
|
a4d3ef |
_GC_OFFSET_MAX
|
|
|
a4d3ef |
};
|
|
|
a4d3ef |
|
|
|
a4d3ef |
+static void unit_gc_mark_good(Unit *u, unsigned gc_marker)
|
|
|
a4d3ef |
+{
|
|
|
a4d3ef |
+ Iterator i;
|
|
|
a4d3ef |
+ Unit *other;
|
|
|
a4d3ef |
+
|
|
|
a4d3ef |
+ u->gc_marker = gc_marker + GC_OFFSET_GOOD;
|
|
|
a4d3ef |
+
|
|
|
a4d3ef |
+ /* Recursively mark referenced units as GOOD as well */
|
|
|
a4d3ef |
+ SET_FOREACH(other, u->dependencies[UNIT_REFERENCES], i)
|
|
|
a4d3ef |
+ if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
|
|
|
a4d3ef |
+ unit_gc_mark_good(other, gc_marker);
|
|
|
a4d3ef |
+}
|
|
|
a4d3ef |
+
|
|
|
a4d3ef |
static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
|
|
|
a4d3ef |
Iterator i;
|
|
|
a4d3ef |
Unit *other;
|
|
|
1abbee |
@@ -847,6 +860,7 @@ static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
|
|
|
a4d3ef |
|
|
|
a4d3ef |
if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
|
|
|
a4d3ef |
u->gc_marker == gc_marker + GC_OFFSET_BAD ||
|
|
|
a4d3ef |
+ u->gc_marker == gc_marker + GC_OFFSET_UNSURE ||
|
|
|
a4d3ef |
u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
|
|
|
a4d3ef |
return;
|
|
|
a4d3ef |
|
|
|
1abbee |
@@ -887,7 +901,7 @@ bad:
|
|
|
a4d3ef |
return;
|
|
|
a4d3ef |
|
|
|
a4d3ef |
good:
|
|
|
a4d3ef |
- u->gc_marker = gc_marker + GC_OFFSET_GOOD;
|
|
|
a4d3ef |
+ unit_gc_mark_good(u, gc_marker);
|
|
|
a4d3ef |
}
|
|
|
a4d3ef |
|
|
|
a4d3ef |
static unsigned manager_dispatch_gc_queue(Manager *m) {
|