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 |