Our pthread_getaffinity_np() implementation had a problem that an unpinned
thread might appear pinned if it was temporarily holding a migration_lock.

Starting in commit 558b963c3f5321cf1c80d03808ed464460fa0647, we can actually
tell these situations apart - a deliberate pin() vs. a temporary migration
lock - so let's start using it.

Refs #776.

Signed-off-by: Nadav Har'El <[email protected]>
---
 include/osv/sched.hh |  1 +
 libc/pthread.cc      | 13 +++++--------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/osv/sched.hh b/include/osv/sched.hh
index 2ff1d00..261bcfd 100644
--- a/include/osv/sched.hh
+++ b/include/osv/sched.hh
@@ -505,6 +505,7 @@ public:
     }
     static osv::application *current_app();
     bool migratable() const { return _migration_lock_counter == 0; }
+    bool pinned() const { return _pinned; }
     /**
      * Return thread's numeric id
      *
diff --git a/libc/pthread.cc b/libc/pthread.cc
index ac783bc..1675ce9 100644
--- a/libc/pthread.cc
+++ b/libc/pthread.cc
@@ -1007,15 +1007,12 @@ int pthread_getaffinity_np(const pthread_t thread, 
size_t cpusetsize,
     }
     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. The closest feature we have in OSv is
-    // the knowledge of whether *right now* the thread is pinned to a single
-    // CPU, and if not it can run on all cpus. Note that this thread (if not
-    // the current thread) might be only temporarily pinned - e.g. inside a
-    // migration_lock while accessing a per-cpu variable.
-    // FIXME: For better support of this feature, we'll need to add
-    // a per-thread cpuset, separate from _migration_lock_counter.
+    // 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.migratable()) {
+    if (!t.pinned()) {
         for (unsigned i = 0; i < sched::cpus.size(); i++) {
             CPU_SET(i, 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.

Reply via email to