commit 2b53b3334fea4e6f64a3aec9e2487e711f9a77dd Author: KOSAKI Motohiro Date: Wed Oct 1 16:50:59 2014 -0400 * ext/etc/etc.c (etc_nprocessors_affinity): use sched_getaffinity for getting precious number of available cpus. * ext/etc/etc.c (etc_nprocessors): use etc_nprocessors_affinity if possible. diff --git a/ChangeLog b/ChangeLog index 35a55ab..cfec9fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Thu Oct 2 05:50:59 2014 KOSAKI Motohiro + + * ext/etc/etc.c (etc_nprocessors_affinity): use sched_getaffinity + for getting precious number of available cpus. + * ext/etc/etc.c (etc_nprocessors): use etc_nprocessors_affinity if + possible. + Thu Oct 2 03:42:12 2014 Tanaka Akira * ext/etc/etc.c (etc_nprocessors_online): New method. diff --git a/configure.in b/configure.in index c6142a4..70de1a7 100644 --- a/configure.in +++ b/configure.in @@ -2033,6 +2033,7 @@ AC_CHECK_FUNCS(pread) AC_CHECK_FUNCS(qsort_r) AC_CHECK_FUNCS(readlink) AC_CHECK_FUNCS(round) +AC_CHECK_FUNCS(sched_getaffinity) AC_CHECK_FUNCS(seekdir) AC_CHECK_FUNCS(select_large_fdset) AC_CHECK_FUNCS(sendfile) diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 2546560..6a596cb 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -30,6 +30,10 @@ #include #endif +#ifdef HAVE_SCHED_GETAFFINITY +#include +#endif + static VALUE sPasswd; #ifdef HAVE_GETGRENT static VALUE sGroup; @@ -891,7 +895,35 @@ io_pathconf(VALUE io, VALUE arg) #define io_pathconf rb_f_notimplement #endif + #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) +#ifdef HAVE_SCHED_GETAFFINITY +static VALUE +etc_nprocessors_affinity(long ncpus) +{ + cpu_set_t *cpuset; + size_t size; + int ret; + + cpuset = CPU_ALLOC((int)ncpus); + if (!cpuset) { + rb_sys_fail("CPU_ALLOC"); + } + size = CPU_ALLOC_SIZE(ncpus); + CPU_ZERO_S(size, cpuset); + + ret = sched_getaffinity(0, size, cpuset); + if (ret==-1) { + rb_sys_fail("sched_getaffinity"); + } + + ret = CPU_COUNT_S(size, cpuset); + CPU_FREE(cpuset); + + return INT2NUM(ret); +} +#endif + /* * Returns the number of online processors. * @@ -900,12 +932,21 @@ io_pathconf(VALUE io, VALUE arg) * * This method is implemented as: * - sysconf(_SC_NPROCESSORS_ONLN): GNU/Linux, NetBSD, FreeBSD, OpenBSD, DragonFly BSD, OpenIndiana, Mac OS X, AIX + * - sched_getaffinity(): Linux * * Example: * * require 'etc' * p Etc.nprocessors #=> 4 * + * The result might be smaller number than physical cpus especially when ruby + * process is bound to specific cpus. This is intended for getting better + * parallel processing. + * + * Example: (Linux) + * + * $ taskset 0x3 ./ruby -retc -e "p Etc.nprocessors" #=> 2 + * */ static VALUE etc_nprocessors(VALUE obj) @@ -917,6 +958,11 @@ etc_nprocessors(VALUE obj) if (ret == -1) { rb_sys_fail("sysconf(_SC_NPROCESSORS_ONLN)"); } + +#ifdef HAVE_SCHED_GETAFFINITY + return etc_nprocessors_affinity(ret); +#endif + return LONG2NUM(ret); } #else