From: Nadav Har'El <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master
libc: sched_getaffinity() on other threads
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]>
Message-Id: <[email protected]>
---
diff --git a/libc/pthread.cc b/libc/pthread.cc
--- 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);
-}
--
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.