https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=a7d7b9e32f8743b818cbe97dd06f3f16703c671b

commit a7d7b9e32f8743b818cbe97dd06f3f16703c671b
Author:     Mark Geisert <m...@maxrnd.com>
AuthorDate: Tue Mar 18 00:53:57 2025 -0700
Commit:     Corinna Vinschen <cori...@vinschen.de>
CommitDate: Tue Mar 18 10:26:40 2025 +0100

    Cygwin: Carry process affinity through to result
    
    Due to deficient testing, the current code doesn't return a valid result
    to users of sched_getaffinity().  The updated code carries the determined
    procmask through to the generation of result cpu mask.
    
    Recognize Windows' limitation that if the process is multi-group (i.e.,
    has threads in multiple cpu groups) there is no visibility to which
    processors in other groups are being used.  One could remedy this by
    looping through all the process' threads, but that could be expensive
    so is left for future contemplation.  In addition, we'd have to maintain
    our own copy of each thread's current group and mask in internal overhead.
    (By the way, multi-group processes are only possible on Windows systems
    with more than 64 hardware threads.)
    
    Reported-by: Christian Franke <christian.fra...@t-online.de>
    Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257616.html
    Signed-off-by: Mark Geisert <m...@maxrnd.com>
    Fixes: 641ecb07533e ("Cygwin: Implement sched_[gs]etaffinity()")

Diff:
---
 winsup/cygwin/release/3.6.0 |  4 ++++
 winsup/cygwin/sched.cc      | 11 +++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/release/3.6.0 b/winsup/cygwin/release/3.6.0
index d48ee114db82..ad4a6f5dc7d3 100644
--- a/winsup/cygwin/release/3.6.0
+++ b/winsup/cygwin/release/3.6.0
@@ -132,3 +132,7 @@ Fixes:
 - Fix starving of auxiliary signal return address stack in case signal
   handlers bail out (longjmp/setcontext).
   Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257648.html
+
+- Fix sched_getaffinity(2) to carry determined process affinity all the way
+  through to the returned result.
+  Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257616.html
diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc
index 2f4fbc31a786..e15daad263e3 100644
--- a/winsup/cygwin/sched.cc
+++ b/winsup/cygwin/sched.cc
@@ -587,9 +587,16 @@ __sched_getaffinity_sys (pid_t pid, size_t sizeof_set, 
cpu_set_t *set)
          goto done;
        }
 
-      KAFFINITY miscmask = groupmask (__get_cpus_per_group ());
+      KAFFINITY fullmask = groupmask (__get_cpus_per_group ());
+      /* if process is multi-group, we don't have processor visibility. */
+      /*TODO We could provide the missing Windows visibility by book-keeping
+        each thread's current group and mask in our thread overhead, updating
+        them on sched_set_thread_affinity() calls. We could then assemble the
+        total mask here by looping through all threads. */
+      if (groupcount > 1)
+       procmask = fullmask;
       for (int i = 0; i < groupcount; i++)
-       setgroup (sizeof_set, set, grouparray[i], miscmask);
+       setgroup (sizeof_set, set, grouparray[i], fullmask & procmask);
     }
   else
     status = ESRCH;

Reply via email to