From fff17ad73f6ae6b75ef293e17a837f23f6134753 Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Wed, 26 Jun 2019 02:44:56 -0700 Subject: [PATCH] Cygwin: Fix return value of sched_getaffinity Have sched_getaffinity() interface like glibc's, and provide an undocumented internal interface __sched_getaffinity_sys() like the Linux kernel's sched_getaffinity() for benefit of taskset(1). --- winsup/cygwin/common.din | 1 + winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/include/sys/cpuset.h | 10 +++++++++ winsup/cygwin/sched.cc | 29 +++++++++++++++++--------- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 81292ab7b..9cb67992b 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -98,6 +98,7 @@ __res_querydomain SIGFE __res_search SIGFE __res_send SIGFE __res_state SIGFE +__sched_getaffinity_sys SIGFE __signbitd NOSIGFE __signbitf NOSIGFE __signgam NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index b70b9e281..f47055d84 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -510,7 +510,7 @@ details. */ 337: MOUNT_BINARY -> MOUNT_TEXT 338: Export secure_getenv. 339: Export sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, - pthread_setaffinity_np. + pthread_setaffinity_np, __sched_getaffinity_sys. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ diff --git a/winsup/cygwin/include/sys/cpuset.h b/winsup/cygwin/include/sys/cpuset.h index a83163d01..4857b879d 100644 --- a/winsup/cygwin/include/sys/cpuset.h +++ b/winsup/cygwin/include/sys/cpuset.h @@ -9,6 +9,10 @@ details. */ #ifndef _SYS_CPUSET_H_ #define _SYS_CPUSET_H_ +#ifdef __cplusplus +extern "C" { +#endif + typedef __SIZE_TYPE__ __cpu_mask; #define __CPU_SETSIZE 1024 // maximum number of logical processors tracked #define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group @@ -22,4 +26,10 @@ typedef struct __cpu_mask __bits[__CPU_GROUPMAX]; } cpu_set_t; +int __sched_getaffinity_sys (pid_t, size_t, cpu_set_t *); + +#ifdef __cplusplus +} +#endif + #endif /* _SYS_CPUSET_H_ */ diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc index e7b44d319..fdb8ba738 100644 --- a/winsup/cygwin/sched.cc +++ b/winsup/cygwin/sched.cc @@ -555,8 +555,9 @@ done: } int -sched_getaffinity (pid_t pid, size_t sizeof_set, cpu_set_t *set) +__sched_getaffinity_sys (pid_t pid, size_t sizeof_set, cpu_set_t *set) { + /* Emulate Linux raw sched_getaffinity syscall for benefit of taskset(1) */ HANDLE process = 0; int status = 0; @@ -603,14 +604,21 @@ done: if (status) { set_errno (status); - status = -1; + return -1; } - else - { - /* Emulate documented Linux kernel behavior on successful return */ - status = wincap.cpu_count (); - } - return status; + + /* On successful return, we would ordinarily return 0, but instead we + emulate the behavior of the raw sched_getaffinity syscall on Linux. */ + return min (sizeof_set, sizeof (cpu_set_t)); +} + +int +sched_getaffinity (pid_t pid, size_t sizeof_set, cpu_set_t *set) +{ + /* Emulate the Linux glibc interface of sched_getaffinity() by calling + the raw syscall emulation and mapping positive results to 0. */ + int status = __sched_getaffinity_sys (pid, sizeof_set, set); + return status > 0 ? 0 : status; } int @@ -727,9 +735,10 @@ done: if (status) { set_errno (status); - status = -1; + return -1; } - return status; + + return 0; } } /* extern C */