Gentoo Archives: gentoo-portage-dev

From: Florian Schmaus <flo@×××××××××.eu>
To: gentoo-portage-dev@l.g.o
Cc: Florian Schmaus <flo@×××××××××.eu>
Subject: [gentoo-portage-dev] [PATCH] PORTAGE_NICENESS: Consider autogroup scheduling
Date: Sun, 21 Mar 2021 11:22:20
Message-Id: 20210321112215.231905-1-flo@geekplace.eu
1 With Linux's autogroup scheduling feature (CONFIG_SCHED_AUTOGROUP)
2 setting a nice value on a per-process base has only an effect for
3 scheduling decisions relative to the other threads in the same
4 session (typically: the same terminal window). See the section "The
5 nice value and group scheduling" in the sched(7) man page.
6
7 Basically this means that portage "just" setting the nice value, has
8 no effect in presence of autogroup scheduling being active (which is
9 probably true for most (desktop) user systems).
10
11 This commit changes emerge to set the autogroup's nice value, instead
12 of the processes' nice value, in case autogroups are present (detected
13 by the existence of /proc/self/autogroup). The tricky part about
14 autogroup nice values is that we want restore the orignal nice value
15 once we are finished. As otherwise, the session, e.g. your terminal,
16 would continue using this value, and so would subsequently executed
17 processes. For that we use Python's atexit functinaly, to register a
18 function that will restore the orignal nice value of the autogroup.
19
20 Bug: https://bugs.gentoo.org/777492
21 Signed-off-by: Florian Schmaus <flo@×××××××××.eu>
22 ---
23 lib/_emerge/actions.py | 46 +++++++++++++++++++++++++++++++++++-------
24 1 file changed, 39 insertions(+), 7 deletions(-)
25
26 diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
27 index 239bf6f476d1..8f6e7c51b6dc 100644
28 --- a/lib/_emerge/actions.py
29 +++ b/lib/_emerge/actions.py
30 @@ -1,6 +1,7 @@
31 # Copyright 1999-2020 Gentoo Authors
32 # Distributed under the terms of the GNU General Public License v2
33
34 +import atexit
35 import collections
36 import logging
37 import operator
38 @@ -14,6 +15,7 @@ import textwrap
39 import time
40 import warnings
41 from itertools import chain
42 +from pathlib import Path
43
44 import portage
45 portage.proxy.lazyimport.lazyimport(globals(),
46 @@ -2632,13 +2634,43 @@ def apply_priorities(settings):
47 nice(settings)
48
49 def nice(settings):
50 - try:
51 - os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
52 - except (OSError, ValueError) as e:
53 - out = portage.output.EOutput()
54 - out.eerror("Failed to change nice value to '%s'" % \
55 - settings.get("PORTAGE_NICENESS", "0"))
56 - out.eerror("%s\n" % str(e))
57 + autogroup_file = Path("/proc/self/autogroup")
58 +
59 + nice_value : str = settings.get("PORTAGE_NICENESS", "0")
60 +
61 + if not autogroup_file.is_file():
62 + # Autogroup scheduling is not enabled on this system,
63 + # continue using good ol' os.nice().
64 + try:
65 + os.nice(int(nice_value))
66 + except (OSError, ValueError) as e:
67 + out = portage.output.EOutput()
68 + out.eerror("Failed to change nice value to '%s'" % \
69 + settings.get("PORTAGE_NICENESS", "0"))
70 + out.eerror("%s\n" % str(e))
71 + return
72 +
73 + with autogroup_file.open('r+') as f:
74 + line = f.readline()
75 + original_autogroup_nice_value = line.split(' ')[2]
76 +
77 + # We need to restore the original nice value of the
78 + # autogroup, as otherwise the session, e.g. the
79 + # terminal where protage was executed in, would
80 + # continue running with that value.
81 + atexit.register(
82 + lambda value: autogroup_file.open('w').write(value),
83 + original_autogroup_nice_value
84 + )
85 +
86 + try:
87 + f.write(nice_value)
88 + except (OSError) as e:
89 + out = portage.output.EOutput()
90 + out.eerror("Failed to change nice value to '%s'" % \
91 + settings.get("PORTAGE_NICENESS", "0"))
92 + out.eerror("%s\n" % str(e))
93 +
94
95 def ionice(settings):
96
97 --
98 2.26.3