We support pthread_getaffinity_np() on other threads, not just on the current thread. This patch adds this support also for sched_getaffinity().
Since both functions behave almost the same, the patch creates a single function which both of them will call. Note how the return values differ, though: pthread_getaffinity_np() follows pthread tradition and returns errors directly, while sched_getaffinity() follows Unix tradition and returns errors in errno. Fixes #776. Signed-off-by: Nadav Har'El <[email protected]> --- libc/pthread.cc | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/libc/pthread.cc b/libc/pthread.cc index 1675ce9..631eb08 100644 --- a/libc/pthread.cc +++ b/libc/pthread.cc @@ -998,26 +998,57 @@ int sched_setaffinity(pid_t pid, size_t cpusetsize, return 0; } -int pthread_getaffinity_np(const pthread_t thread, size_t cpusetsize, +static int getaffinity(const sched::thread *t, size_t cpusetsize, cpu_set_t *cpuset) { if (sched::cpus.size() > cpusetsize * 8) { // not enough room in cpuset return EINVAL; } - sched::thread &t = pthread::from_libc(thread)->_thread; // Currently OSv does not have a real notion of a list of allowable // CPUs for a thread, as Linux does, but we have the notion of pinning // the thread to a single CPU. Note that if the CPU is only temporarily // bound to a CPU with a migration_lock (e.g., while accessing a per-cpu // variable), it is not considered pinned. memset(cpuset, 0, cpusetsize); - if (!t.pinned()) { + if (!t->pinned()) { for (unsigned i = 0; i < sched::cpus.size(); i++) { CPU_SET(i, cpuset); } } else { - CPU_SET(t.tcpu()->id, cpuset); + CPU_SET(t->tcpu()->id, cpuset); + } + return 0; +} + +int pthread_getaffinity_np(const pthread_t thread, size_t cpusetsize, + cpu_set_t *cpuset) +{ + const sched::thread *t = &pthread::from_libc(thread)->_thread; + return getaffinity(t, cpusetsize, cpuset); +} + +int sched_getaffinity(pid_t pid, size_t cpusetsize, + cpu_set_t *cpuset) +{ + sched::thread *t; + if (pid == 0) { + t = sched::thread::current(); + } else { + t = sched::thread::find_by_id(pid); + if (!t) { + errno = ESRCH; + return -1; + } + // TODO: After the thread was found, if it exits the code below + // may crash. Perhaps we should have a version of find_by_id(), + // with_thread_by_id(pid, func), which holds thread_map_mutex while + // func runs. + } + int err = getaffinity(t, cpusetsize, cpuset); + if (err) { + errno = err; + return -1; } return 0; } @@ -1042,13 +1073,3 @@ int pthread_attr_getaffinity_np(const pthread_attr_t *attr, size_t cpusetsize, return 0; } - -int sched_getaffinity(pid_t pid, size_t cpusetsize, - cpu_set_t *cpuset) -{ - if (pid != 0 && (unsigned int)pid != sched::thread::current()->id()) { - WARN_STUBBED(); - return EINVAL; - } - return pthread_getaffinity_np(pthread_self(), cpusetsize, cpuset); -} -- 2.5.5 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
