--- 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