[PATCH] Cygwin: sched_setscheduler: accept SCHED_OTHER, SCHED_FIFO and SCHED_RR

Christian Franke Christian.Franke@t-online.de
Tue Dec 3 14:51:15 GMT 2024


Corinna Vinschen wrote:
> On Dec  3 10:20, Christian Franke wrote:
>> Brian Inglis wrote:
>>> On 2024-12-02 11:28, ASSI wrote:
>>>> Christian Franke writes:
>>>>> +    nice value   sched_priority Windows priority class
>>>>> +     12...19      1....6          IDLE_PRIORITY_CLASS
>>>>> +      4...11      7...12          BELOW_NORMAL_PRIORITY_CLASS
>>>>> +     -4....3     13...18          NORMAL_PRIORITY_CLASS
>>>>> +    -12...-5     19...24          ABOVE_NORMAL_PRIORITY_CLASS
>>>>> +    -13..-19     25...30          HIGH_PRIORITY_CLASS
>>>>> +         -20     31...32          REALTIME_PRIORITY_CLASS
>>>> That mapping looks odd… care to explain why the number of nice values
>>>> and sched_priorities doesn't match up for each priority class? 39
>>>> possible values for one can't match to 32 for the other of course, but
>>>> which ones are skipped and why?
>>> See also miscfuncs.cc which maps nice<->winprio with a 40 entry table,
>>> and cygwin-doc proc(5) or cygwin-ug-net/proc.html which explains the
>>> mapping to scheduler priorities and policies.
>> No *_PRIORITY_CLASS is mentioned in current newlib-cygwin/winsup/doc/*.
>>
>>
>>> Also relevant may be man-pages-posix sched.h(0p), man-pages-linux
>>> sched(7) and proc_pid_stat(5).
>>>
>>> You may also wish to consider whether SCHED_SPORADIC should be somewhat
>>> supported for POSIX compatibility, and SCHED_IDLE, SCHED_BATCH,
>>> SCHED_DEADLINE for Linux compatibility?
>> SCHED_IDLE: Ignore nice value and set IDLE_PRIORITY_CLASS ?
> Would make sense, I guess.

Patch on top of original patch attached.


>
>> SCHED_BATCH: Reduced mapping, e.g. nice=0 -> BELOW_NORMAL_PRIORITY_CLASS ?
> Sounds good.

More complex, topic suggests to do some rework of the nice<->winprio 
mapping functions first.


>
>> SCHED_SPORADIC, SCHED_DEADLINE: ?
> We can't model SCHED_DEADLINE in Windows.
>
>> The current newlib/libc/include/sys/sched.h only defines SCHED_OTHER,
>> SCHED_FIFO, SCHED_RR and SCHED_SPORADIC. The latter is guarded by
>> _POSIX_SPORADIC_SERVER which is only set for RTEMS (#ifdef __rtems__) in
>> features.h.
> SCHED_SPORADIC is a bit of a problem.  It requires extension of the
> sched_param struct with values we're not able to handle.
>
> Also, SCHED_SPORADIC doesn't exist in Linux either, so why bother.

Let's forget these.

-------------- next part --------------
From 0ffa0beb2d4f845b9c3ac6a5be842147163d26a2 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.franke@t-online.de>
Date: Tue, 3 Dec 2024 15:42:50 +0100
Subject: [PATCH] Cygwin: sched_setscheduler: accept SCHED_IDLE

Add SCHED_IDLE to <sys/sched.h>.  If SCHED_IDLE is selected, preserve
the nice value and set the Windows priority to IDLE_PRIORITY_CLASS.

Signed-off-by: Christian Franke <christian.franke@t-online.de>
---
 newlib/libc/include/sys/sched.h |  4 ++++
 winsup/cygwin/release/3.6.0     | 10 ++++++----
 winsup/cygwin/sched.cc          |  9 +++++++--
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/newlib/libc/include/sys/sched.h b/newlib/libc/include/sys/sched.h
index 4adb6e2d6..c96355c24 100644
--- a/newlib/libc/include/sys/sched.h
+++ b/newlib/libc/include/sys/sched.h
@@ -42,6 +42,10 @@ extern "C" {
 #define SCHED_SPORADIC 4
 #endif
 
+#if __GNU_VISIBLE
+#define SCHED_IDLE     5
+#endif
+
 /* Scheduling Parameters */
 /* Open Group Specifications Issue 6 */
 
diff --git a/winsup/cygwin/release/3.6.0 b/winsup/cygwin/release/3.6.0
index 9e924dabb..8ca91f0c9 100644
--- a/winsup/cygwin/release/3.6.0
+++ b/winsup/cygwin/release/3.6.0
@@ -54,9 +54,11 @@ What changed:
   to POSIX and Linux (glibc >= 2.2.4) behavior.
 
 - sched_setscheduler(2) now emulates changes between SCHED_OTHER,
-  SCHED_FIFO and SCHED_RR.  If SCHED_OTHER is selected, the Windows
-  priority is set according to the nice value.  If SCHED_FIFO or
-  SCHED_RR is selected, the nice value is preserved and the Windows
-  priority is set according to the realtime priority.
+  SCHED_IDLE, SCHED_FIFO and SCHED_RR.  If SCHED_OTHER is selected, the
+  Windows priority is set according to the nice value. If SCHED_IDLE is
+  selected, the nice value is preserved and the Windows 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.
   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 c48c433d7..8b4e7efc4 100644
--- a/winsup/cygwin/sched.cc
+++ b/winsup/cygwin/sched.cc
@@ -34,6 +34,7 @@ sched_get_priority_max (int policy)
   switch (policy)
     {
     case SCHED_OTHER:
+    case SCHED_IDLE:
       return 0;
     case SCHED_FIFO:
     case SCHED_RR:
@@ -50,6 +51,7 @@ sched_get_priority_min (int policy)
   switch (policy)
     {
     case SCHED_OTHER:
+    case SCHED_IDLE:
       return 0;
     case SCHED_FIFO:
     case SCHED_RR:
@@ -93,7 +95,7 @@ sched_getparam (pid_t pid, struct sched_param *param)
       return -1;
     }
 
-  if (p->sched_policy == SCHED_OTHER)
+  if (p->sched_policy == SCHED_OTHER || p->sched_policy == SCHED_IDLE)
     {
       /* No realtime policy. */
       param->sched_priority = 0;
@@ -235,6 +237,9 @@ sched_setparam_pinfo (pinfo & p, const struct sched_param *param)
   if (p->sched_policy == SCHED_OTHER && pri == 0)
     /* No realtime policy, reapply the nice value. */
     pclass = nice_to_winprio (p->nice);
+  else if (p->sched_policy == SCHED_IDLE && pri == 0)
+    /* Idle policy, ignore the nice value. */
+    pclass = IDLE_PRIORITY_CLASS;
   else if (1 <= pri && pri <= 6)
     pclass = IDLE_PRIORITY_CLASS;
   else if (pri <= 12)
@@ -417,7 +422,7 @@ sched_setscheduler (pid_t pid, int policy,
 		    const struct sched_param *param)
 {
   if (!(pid >= 0 && param &&
-      ((policy == SCHED_OTHER && param->sched_priority == 0) ||
+      (((policy == SCHED_OTHER || policy == SCHED_IDLE) && param->sched_priority == 0) ||
       ((policy == SCHED_FIFO || policy == SCHED_RR) && valid_sched_parameters(param)))))
     {
       set_errno (EINVAL);
-- 
2.45.1



More information about the Cygwin-patches mailing list