Reviewed-by: Benoît Canet <ben...@scylladb.com>

2017-01-18 10:32 GMT+01:00 Nadav Har'El <n...@scylladb.com>:

> Allow unpinning a thread with pthread_setaffinity_np() and
> sched_setaffinity() by setting the CPU mask to all CPUs.
>
> We still do not support setting the CPU mask to an arbitrary subset of
> CPUs - just to either one CPU, or all of them.
>
> Fixes #778
>
> Signed-off-by: Nadav Har'El <n...@scylladb.com>
> ---
>  libc/pthread.cc               |  2 ++
>  tests/tst-pthread-affinity.cc | 47 ++++++++++++++++++++++++++++++
> +++++++++++++
>  2 files changed, 49 insertions(+)
>
> diff --git a/libc/pthread.cc b/libc/pthread.cc
> index 62de17d..1322a26 100644
> --- a/libc/pthread.cc
> +++ b/libc/pthread.cc
> @@ -1013,6 +1013,8 @@ static int setaffinity(sched::thread* t, size_t
> cpusetsize,
>                  }
>              }
>          }
> +    } else if (count == (int)sched::cpus.size()) {
> +        t->unpin();
>      } else {
>          WARN_ONCE("Warning: OSv only supports cpu_set_t with at most one "
>                  "CPU set.\n pthread_setaffinity_np or sched_setaffinity
> ignored.\n");
> diff --git a/tests/tst-pthread-affinity.cc b/tests/tst-pthread-affinity.cc
> index 142b6a7..b62924f 100644
> --- a/tests/tst-pthread-affinity.cc
> +++ b/tests/tst-pthread-affinity.cc
> @@ -35,6 +35,49 @@ void *get_processor(void *cpuid)
>      return NULL;
>  }
>
> +// Test that we can pin an existing thread to a specific CPU and then to
> unpin
> +// it by changing its affinity to all CPUs. Currently we test this only
> on the
> +// current thread.
> +void *test_pin_unpin(void *)
> +{
> +    unsigned ncpus = sched::cpus.size();
> +    // The thread starts with affinity to all cpus
> +    cpu_set_t cs;
> +    CPU_ZERO(&cs);
> +    report("getaffinity", pthread_getaffinity_np(pthread_self(),
> sizeof(cs), &cs) == 0);
> +    bool success = true;
> +    for (unsigned i = 0; i < ncpus; i++) {
> +        success = success && CPU_ISSET(i, &cs);
> +    }
> +    report("thread is initially unpinned", success);
> +    // Pin the thread to cpu 0 only, and check it worked
> +    CPU_ZERO(&cs);
> +    CPU_SET(0, &cs);
> +    report("setaffinity", pthread_setaffinity_np(pthread_self(),
> sizeof(cs), &cs) == 0);
> +    CPU_ZERO(&cs);
> +    report("getaffinity", pthread_getaffinity_np(pthread_self(),
> sizeof(cs), &cs) == 0);
> +    success = CPU_ISSET(0, &cs);
> +    for (unsigned i = 1; i < ncpus; i++) {
> +        success = success && !CPU_ISSET(i, &cs);
> +    }
> +    report("thread is now pinned to cpu 0", success);
> +    // Unpin the thread (set its affinity to all CPUs) and confirm it
> worked
> +    CPU_ZERO(&cs);
> +    for (unsigned i = 0; i < ncpus; i++) {
> +        CPU_SET(i, &cs);
> +    }
> +    report("setaffinity", pthread_setaffinity_np(pthread_self(),
> sizeof(cs), &cs) == 0);
> +    CPU_ZERO(&cs);
> +    report("getaffinity", pthread_getaffinity_np(pthread_self(),
> sizeof(cs), &cs) == 0);
> +    success = true;
> +    for (unsigned i = 0; i < ncpus; i++) {
> +        success = success && CPU_ISSET(i, &cs);
> +    }
> +    report("thread is now unpinned again", success);
> +
> +    return nullptr;
> +}
> +
>  int main(void)
>  {
>      printf("starting pthread affinity test\n");
> @@ -111,6 +154,10 @@ int main(void)
>      }
>      report("All bits were set", success);
>
> +    // Test that we can pin and unpin an existing thread
> +    pthread_create(&thread, nullptr, test_pin_unpin, nullptr);
> +    pthread_join(thread, nullptr);
> +
>      printf("SUMMARY: %u tests / %u failures\n", tests_total.load(),
> tests_failed.load());
>      return tests_failed == 0 ? 0 : 1;
>  }
> --
> 2.9.3
>
> --
> 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 osv-dev+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to