[PATCH] Implement sched_[gs]etaffinity()

Mark Geisert mark@maxrnd.com
Thu Apr 11 04:06:00 GMT 2019


---
 newlib/libc/include/sched.h |  4 +++
 winsup/cygwin/sched.cc      | 68 +++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/newlib/libc/include/sched.h b/newlib/libc/include/sched.h
index 1016235bb..e3a5b97e5 100644
--- a/newlib/libc/include/sched.h
+++ b/newlib/libc/include/sched.h
@@ -92,6 +92,10 @@ int sched_yield( void );
 
 #if __GNU_VISIBLE
 int sched_getcpu(void);
+
+typedef uint64_t cpu_set_t; /* ...until cpuset(7) exists */
+int sched_getaffinity(pid_t, size_t, cpu_set_t *);
+int sched_setaffinity(pid_t, size_t, const cpu_set_t *);
 #endif
 
 #ifdef __cplusplus
diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc
index 10168e641..496e08857 100644
--- a/winsup/cygwin/sched.cc
+++ b/winsup/cygwin/sched.cc
@@ -424,4 +424,72 @@ sched_getcpu ()
   return pnum.Group * __get_cpus_per_group () + pnum.Number;
 }
 
+int
+sched_getaffinity (pid_t pid, size_t cpusetsize, cpu_set_t *mask)
+{
+  int status = 0;
+  HANDLE process = pid ? OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)
+                       : GetCurrentProcess ();
+  if (process)
+    {
+      DWORD_PTR process_affinity; /* 4 (8) bytes on 32- (64-) bit Windows */
+      DWORD_PTR system_affinity;  /* ditto */
+
+      if (!GetProcessAffinityMask (process,&process_affinity, &system_affinity))
+	{
+	  status = geterrno_from_win_error (GetLastError (), EPERM);
+	  goto done;
+	}
+      memset (mask, 0, cpusetsize);
+      memcpy (mask, &process_affinity,
+	      min(cpusetsize, sizeof (process_affinity)));
+    }
+  else
+    status = ESRCH;
+
+done:
+  if (process && (process != GetCurrentProcess ()))
+    CloseHandle (process);
+
+  if (status)
+    {
+      set_errno (status);
+      status = -1;
+    }
+  return status;
+}
+
+int
+sched_setaffinity (pid_t pid, size_t cpusetsize, const cpu_set_t *mask)
+{
+  int status = 0;
+  HANDLE process = pid ? OpenProcess (PROCESS_SET_INFORMATION, FALSE, pid)
+                       : GetCurrentProcess ();
+  if (process)
+    {
+      DWORD_PTR process_affinity = 0; /* 4 (8) bytes on 32- (64-) bit Windows */
+
+      memcpy (&process_affinity, mask,
+	      min(cpusetsize, sizeof (process_affinity)));
+      if (!SetProcessAffinityMask (process, process_affinity))
+	{
+	  status = geterrno_from_win_error (GetLastError (), EPERM);
+	  goto done;
+	}
+    }
+  else
+    status = ESRCH;
+
+done:
+  if (process && (process != GetCurrentProcess ()))
+    CloseHandle (process);
+
+  if (status)
+    {
+      set_errno (status);
+      status = -1;
+    }
+  return status;
+}
+
 } /* extern C */
-- 
2.17.0



More information about the Cygwin-patches mailing list