Christian Franke wrote:
Christian Franke wrote:
Corinna Vinschen wrote:
Hi Christian,
On Dec 6 17:52, Christian Franke wrote:
A first attempt to add SCHED_BATCH.
Still TODO:
- Add SCHED_IDLE/BATCH to winsup/doc/posix.xml
- Provide correct values in (18) and (19) of /proc/PID/stat for
SCHED_BATCH.
- Provide correct value in (18) of /proc/PID/stat for SCHED_FIFO/RR.
--
Regards,
Christian
From 0822917252fdade3edc240b4fbfd3c0f47ef1deb Mon Sep 17 00:00:00
2001
From: Christian Franke <christian.fra...@t-online.de>
Date: Fri, 6 Dec 2024 17:32:29 +0100
Subject: [PATCH] Cygwin: sched_setscheduler: accept SCHED_BATCH
Add SCHED_BATCH to <sys/sched.h>. SCHED_BATCH is similar to
SCHED_OTHER,
except that the nice value is mapped to a one step lower Windows
priority.
Rework the mapping functions to ease the addition of this
functionality.
Signed-off-by: Christian Franke <christian.fra...@t-online.de>
---
newlib/libc/include/sys/sched.h | 8 ++
winsup/cygwin/local_includes/miscfuncs.h | 4 +-
winsup/cygwin/miscfuncs.cc | 155
+++++++++++++----------
winsup/cygwin/release/3.6.0 | 11 +-
winsup/cygwin/sched.cc | 15 ++-
winsup/cygwin/syscalls.cc | 20 +--
6 files changed, 129 insertions(+), 84 deletions(-)
diff --git a/newlib/libc/include/sys/sched.h
b/newlib/libc/include/sys/sched.h
index c96355c24..265215211 100644
--- a/newlib/libc/include/sys/sched.h
+++ b/newlib/libc/include/sys/sched.h
@@ -38,6 +38,14 @@ extern "C" {
#define SCHED_FIFO 1
#define SCHED_RR 2
+#if __GNU_VISIBLE
+#if defined(__CYGWIN__)
+#define SCHED_BATCH 0
+#else
+#define SCHED_BATCH 3
+#endif
+#endif
I would prefer that SCHED_BATCH gets its own, single value.
There's no good reason to add another ifdef for that. Why
not just #define SCHED_BATCH 6?
The idea was to keep the non-Cygwin value in sync with Linux.
https://github.com/torvalds/linux/blob/fac04ef/include/uapi/linux/sched.h#L111
Of course we could drop this idea and use 6.
Attached, no other changes.
The next (and possibly last) SCHED_* feature addition on top of the
SCHED_BATCH (6) patch.
From 56e406c5ab270b2ef3ca31cb8fabfaca927f4d29 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.fra...@t-online.de>
Date: Tue, 10 Dec 2024 15:09:42 +0100
Subject: [PATCH] Cygwin: sched_setscheduler: accept SCHED_RESET_ON_FORK flag
Add SCHED_RESET_ON_FORK to <sys/sched.h>. If this flag is set, SCHED_FIFO
and SCHED_RR are reset to SCHED_OTHER and negative nice values are reset to
zero in each child process created with fork(2).
Signed-off-by: Christian Franke <christian.fra...@t-online.de>
---
newlib/libc/include/sys/sched.h | 3 +++
winsup/cygwin/fork.cc | 33 ++++++++++++++++++++++++++++
winsup/cygwin/local_includes/pinfo.h | 5 +++--
winsup/cygwin/pinfo.cc | 1 +
winsup/cygwin/release/3.6.0 | 3 +++
winsup/cygwin/sched.cc | 11 ++++++----
winsup/cygwin/spawn.cc | 1 +
7 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/newlib/libc/include/sys/sched.h b/newlib/libc/include/sys/sched.h
index 6977d3d4a..95509dbf0 100644
--- a/newlib/libc/include/sys/sched.h
+++ b/newlib/libc/include/sys/sched.h
@@ -45,6 +45,9 @@ extern "C" {
#if __GNU_VISIBLE
#define SCHED_IDLE 5
#define SCHED_BATCH 6
+
+/* Flag to drop realtime policies and negative nice values on fork(). */
+#define SCHED_RESET_ON_FORK 0x40000000
#endif
/* Scheduling Parameters */
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 7d976e882..925f988bf 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -404,6 +404,39 @@ frok::parent (volatile char * volatile stack_here)
child->nice = myself->nice;
child->sched_policy = myself->sched_policy;
+ /* Handle SCHED_RESET_ON_FORK flag. */
+ if (myself->sched_reset_on_fork)
+ {
+ bool batch = (myself->sched_policy == SCHED_BATCH);
+ bool idle = (myself->sched_policy == SCHED_IDLE);
+ bool set_prio = false;
+ /* Reset negative nice values to zero. */
+ if (myself->nice < 0)
+ {
+ child->nice = 0;
+ set_prio = !idle;
+ }
+ /* Reset realtime policies to SCHED_OTHER. */
+ if (!(myself->sched_policy == SCHED_OTHER || batch || idle))
+ {
+ child->sched_policy = SCHED_OTHER;
+ set_prio = true;
+ }
+ /* Adjust Windows priority if required. */
+ if (set_prio)
+ {
+ HANDLE proc = OpenProcess(PROCESS_SET_INFORMATION |
+ PROCESS_QUERY_LIMITED_INFORMATION,
+ FALSE, child->dwProcessId);
+ if (proc)
+ {
+ set_and_check_winprio(proc, nice_to_winprio(child->nice, batch));
+ CloseHandle(proc);
+ }
+ }
+ }
+ child->sched_reset_on_fork = false;
+
/* Initialize things that are done later in dll_crt0_1 that aren't done
for the forkee. */
wcscpy (child->progname, myself->progname);
diff --git a/winsup/cygwin/local_includes/pinfo.h
b/winsup/cygwin/local_includes/pinfo.h
index 03e0c4d60..be5d53021 100644
--- a/winsup/cygwin/local_includes/pinfo.h
+++ b/winsup/cygwin/local_includes/pinfo.h
@@ -93,8 +93,9 @@ public:
struct rusage rusage_self;
struct rusage rusage_children;
- int nice; /* nice value for SCHED_OTHER. */
- int sched_policy; /* SCHED_OTHER, SCHED_FIFO or SCHED_RR. */
+ int nice; /* nice value for SCHED_OTHER and SCHED_BATCH. */
+ int sched_policy; /* SCHED_OTHER/BATCH/IDLE/FIFO/RR */
+ bool sched_reset_on_fork; /* true if SCHED_RESET_ON_FORK flag was set. */
/* Non-zero if process was stopped by a signal. */
char stopsig;
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 06c966f1e..fecf76eb6 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -103,6 +103,7 @@ pinfo_init (char **envp, int envc)
environ_init (NULL, 0); /* call after myself has been set up */
myself->nice = winprio_to_nice (GetPriorityClass (GetCurrentProcess ()));
myself->sched_policy = SCHED_OTHER;
+ myself->sched_reset_on_fork = false;
myself->ppid = 1; /* always set last */
debug_printf ("Set nice to %d", myself->nice);
}
diff --git a/winsup/cygwin/release/3.6.0 b/winsup/cygwin/release/3.6.0
index 11f745b23..d35aa3036 100644
--- a/winsup/cygwin/release/3.6.0
+++ b/winsup/cygwin/release/3.6.0
@@ -61,5 +61,8 @@ What changed:
priority is set to IDLE_PRIORITY_CLASS. If SCHED_FIFO or SCHED_RR is
selected, the nice value is preserved and the Windows priority is set
according to the realtime priority.
+ If the SCHED_RESET_ON_FORK flag is set, SCHED_FIFO and SCHED_RR are
+ reset to SCHED_OTHER and negative nice values are reset to zero in
+ each child process created with fork(2).
Note: Windows does not offer alternative scheduling policies so
this could only emulate API behavior.
diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc
index ec62ea83c..d75a3404f 100644
--- a/winsup/cygwin/sched.cc
+++ b/winsup/cygwin/sched.cc
@@ -162,7 +162,7 @@ sched_getscheduler (pid_t pid)
set_errno (ESRCH);
return -1;
}
- return p->sched_policy;
+ return p->sched_policy | (p->sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0);
}
/* get the time quantum for pid */
@@ -425,9 +425,11 @@ int
sched_setscheduler (pid_t pid, int policy,
const struct sched_param *param)
{
+ int new_policy = policy & ~SCHED_RESET_ON_FORK;
if (!(pid >= 0 && param &&
- (((policy == SCHED_OTHER || policy == SCHED_BATCH || policy ==
SCHED_IDLE)
- && param->sched_priority == 0) || ((policy == SCHED_FIFO || policy ==
SCHED_RR)
+ (((new_policy == SCHED_OTHER || new_policy == SCHED_BATCH
+ || new_policy == SCHED_IDLE) && param->sched_priority == 0)
+ || ((new_policy == SCHED_FIFO || new_policy == SCHED_RR)
&& valid_sched_parameters(param)))))
{
set_errno (EINVAL);
@@ -442,13 +444,14 @@ sched_setscheduler (pid_t pid, int policy,
}
int prev_policy = p->sched_policy;
- p->sched_policy = policy;
+ p->sched_policy = new_policy;
if (sched_setparam_pinfo (p, param))
{
p->sched_policy = prev_policy;
return -1;
}
+ p->sched_reset_on_fork = !!(policy & SCHED_RESET_ON_FORK);
return 0;
}
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 7f9f2df64..8016f0864 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -800,6 +800,7 @@ child_info_spawn::worker (const char *prog_arg, const char
*const *argv,
child->start_time = time (NULL); /* Register child's starting time. */
child->nice = myself->nice;
child->sched_policy = myself->sched_policy;
+ child->sched_reset_on_fork = false;
postfork (child);
if (mode != _P_DETACH
&& (!child.remember () || !child.attach ()))
--
2.45.1