diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 627dc92..7155c88 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -1074,6 +1074,7 @@ etc_nprocessors_affin(void) * This method is implemented using: * - sched_getaffinity(): Linux * - sysconf(_SC_NPROCESSORS_ONLN): GNU/Linux, NetBSD, FreeBSD, OpenBSD, DragonFly BSD, OpenIndiana, Mac OS X, AIX + * - GetActiveProcessorCount(ALL_PROCESSOR_GROUPS): Windows * * *Example:* * @@ -1112,9 +1113,24 @@ etc_nprocessors(VALUE obj) rb_sys_fail("sysconf(_SC_NPROCESSORS_ONLN)"); } #else - SYSTEM_INFO si; - GetSystemInfo(&si); - ret = (long)si.dwNumberOfProcessors; +# ifndef ALL_PROCESSOR_GROUPS +# define ALL_PROCESSOR_GROUPS 0xffff +# endif + /* GetSystemInfo() counts the current processor group only, and mingw-w64 declares GetActiveProcessorCount() only for _WIN32_WINNT >= 0x0601 */ + typedef DWORD (WINAPI *GetActiveProcessorCount_t)(WORD); + GetActiveProcessorCount_t pGetActiveProcessorCount = + (GetActiveProcessorCount_t)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetActiveProcessorCount"); + DWORD n = 0; + + if (pGetActiveProcessorCount) { + n = pGetActiveProcessorCount(ALL_PROCESSOR_GROUPS); + } + if (n == 0) { + SYSTEM_INFO si; + GetSystemInfo(&si); + n = si.dwNumberOfProcessors; + } + ret = (long)n; #endif return LONG2NUM(ret); } diff --git a/test/etc/test_etc.rb b/test/etc/test_etc.rb index c2e3af6..d0e19f3 100644 --- a/test/etc/test_etc.rb +++ b/test/etc/test_etc.rb @@ -167,6 +167,9 @@ def test_pathconf def test_nprocessors n = Etc.nprocessors assert_operator(1, :<=, n) + if /mswin|mingw/ =~ RUBY_PLATFORM + assert_operator(Integer(ENV.fetch("NUMBER_OF_PROCESSORS")), :<=, n) + end end def test_sysconfdir