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.franke@t-online.de>
This commit is contained in:
parent
a31a6fe5dd
commit
06952f41ff
7 changed files with 52 additions and 9 deletions
|
@ -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 */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -64,5 +64,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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ()))
|
||||
|
|
Loading…
Add table
Reference in a new issue