Both patches pushed.
Thanks, Corinna On Dec 11 12:50, Christian Franke wrote: > Corinna Vinschen wrote: > > Hi Christian, > > > > On Dec 10 15:16, Christian Franke wrote: > > > + /* 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; > > > + > > Is it really necessary to go to such length here? For one thing, we > > have hchild aka pi.hProcess, which should have all access rights on the > > child. Otherwise, the priority of the child process can be set in the > > dwCreationFlags parameter, called `c_flags' in frok::parent(). See line > > 215 in fork.cc. > > A new patch setting c_flags directly is attached. > > > In terms of the SCHED_BATCH value, I'm not going to wait much longer. > > If there's no reply on the newlib list tomorrow, I'll push your patch > > with SCHED_BATCH set to 6. > > > > > > Thanks, > > Corinna > > > > From 89dfe62ddaa162b3eb911a42b635ad2769470cf2 Mon Sep 17 00:00:00 2001 > From: Christian Franke <christian.fra...@t-online.de> > Date: Wed, 11 Dec 2024 12:48:58 +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 | 37 +++++++++++++++++++++++++--- > 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, 52 insertions(+), 9 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..41a533705 100644 > --- a/winsup/cygwin/fork.cc > +++ b/winsup/cygwin/fork.cc > @@ -212,7 +212,37 @@ frok::parent (volatile char * volatile stack_here) > bool fix_impersonation = false; > pinfo child; > > - int c_flags = GetPriorityClass (GetCurrentProcess ()); > + /* Inherit scheduling parameters by default. */ > + int child_nice = myself->nice; > + int child_sched_policy = myself->sched_policy; > + int c_flags = 0; > + > + /* 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; > + } > + if (set_prio) > + c_flags = nice_to_winprio (child_nice, batch); > + } > + > + /* Always request a priority because otherwise anything above > + NORMAL_PRIORITY_CLASS would not be inherited. */ > + if (!c_flags) > + c_flags = GetPriorityClass (GetCurrentProcess ()); > debug_printf ("priority class %d", c_flags); > /* Per MSDN, this must be specified even if lpEnvironment is set to NULL, > otherwise UNICODE characters in the parent environment are not copied > @@ -401,8 +431,9 @@ frok::parent (volatile char * volatile stack_here) > goto cleanup; > } > > - child->nice = myself->nice; > - child->sched_policy = myself->sched_policy; > + child->nice = child_nice; > + child->sched_policy = child_sched_policy; > + child->sched_reset_on_fork = false; > > /* Initialize things that are done later in dll_crt0_1 that aren't done > for the forkee. */ > 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 >