diff options
author | Brad King <brad.king@kitware.com> | 2017-09-06 19:01:50 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-03-05 14:21:31 (GMT) |
commit | 24de561a1a7529b919215edb0322279449c5e6c0 (patch) | |
tree | 2114c6687833ed4e9b8872eced3cb1a0953ec578 /Utilities/cmlibuv/src/unix | |
parent | 43d6e5a71f7cb68578c72ece1cb5046b929ebdc0 (diff) | |
download | CMake-24de561a1a7529b919215edb0322279449c5e6c0.zip CMake-24de561a1a7529b919215edb0322279449c5e6c0.tar.gz CMake-24de561a1a7529b919215edb0322279449c5e6c0.tar.bz2 |
libuv: unix,win: add uv_spawn option to set child CPU affinity mask
Implement it on Linux, FreeBSD, and Windows for now, and fail with
UV_ENOTSUP on other platforms.
Backported from upstream libuv PR 1527, scheduled for inclusion
in libuv 2.0.
Diffstat (limited to 'Utilities/cmlibuv/src/unix')
-rw-r--r-- | Utilities/cmlibuv/src/unix/process.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c index 9842710..d7b6ad3 100644 --- a/Utilities/cmlibuv/src/unix/process.c +++ b/Utilities/cmlibuv/src/unix/process.c @@ -32,6 +32,7 @@ #include <unistd.h> #include <fcntl.h> #include <poll.h> +#include <sched.h> #if defined(__APPLE__) && !TARGET_OS_IPHONE # include <crt_externs.h> @@ -44,6 +45,14 @@ extern char **environ; # include <grp.h> #endif +#if defined(__linux__) +# define uv__cpu_set_t cpu_set_t +#elif defined(__FreeBSD__) +# include <sys/param.h> +# include <sys/cpuset.h> +# include <pthread_np.h> +# define uv__cpu_set_t cpuset_t +#endif static void uv__chld(uv_signal_t* handle, int signum) { uv_process_t* process; @@ -285,6 +294,12 @@ static void uv__process_child_init(const uv_process_options_t* options, int err; int fd; int n; +#if defined(__linux__) || defined(__FreeBSD__) + int r; + int i; + int cpumask_size; + uv__cpu_set_t cpuset; +#endif if (options->flags & UV_PROCESS_DETACHED) setsid(); @@ -375,6 +390,26 @@ static void uv__process_child_init(const uv_process_options_t* options, _exit(127); } +#if defined(__linux__) || defined(__FreeBSD__) + if (options->cpumask != NULL) { + cpumask_size = uv_cpumask_size(); + assert(options->cpumask_size >= (size_t)cpumask_size); + + CPU_ZERO(&cpuset); + for (i = 0; i < cpumask_size; ++i) { + if (options->cpumask[i]) { + CPU_SET(i, &cpuset); + } + } + + r = -pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset); + if (r != 0) { + uv__write_int(error_fd, r); + _exit(127); + } + } +#endif + if (options->env != NULL) { environ = options->env; } @@ -429,6 +464,16 @@ int uv_spawn(uv_loop_t* loop, int i; int status; + if (options->cpumask != NULL) { +#if defined(__linux__) || defined(__FreeBSD__) + if (options->cpumask_size < (size_t)uv_cpumask_size()) { + return UV_EINVAL; + } +#else + return UV_ENOTSUP; +#endif + } + assert(options->file != NULL); assert(!(options->flags & ~(UV_PROCESS_DETACHED | UV_PROCESS_SETGID | |