diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 627dc92708f445..1c82c7cda64ad6 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -800,6 +800,8 @@ static VALUE etc_uname(VALUE obj) { #ifdef _WIN32 + typedef long (WINAPI version_func)(OSVERSIONINFOW *); + version_func *pRtlGetVersion; OSVERSIONINFOW v; SYSTEM_INFO s; const char *sysname, *mach; @@ -808,9 +810,11 @@ etc_uname(VALUE obj) DWORD len = 0; WCHAR *buf; + /* GetVersionEx reports 6.2 unless the manifest declares Windows 8.1 or later */ + pRtlGetVersion = (version_func *)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); v.dwOSVersionInfoSize = sizeof(v); - if (!GetVersionExW(&v)) - rb_sys_fail("GetVersionEx"); + if (!pRtlGetVersion || pRtlGetVersion(&v)) + rb_notimplement(); result = rb_hash_new(); sysname = "Windows_NT"; @@ -1074,6 +1078,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 +1117,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/-ext-/gc/test_register.rb b/test/-ext-/gc/test_register.rb index 84a069fcad51cd..23fde2a635ea11 100644 --- a/test/-ext-/gc/test_register.rb +++ b/test/-ext-/gc/test_register.rb @@ -148,7 +148,7 @@ def test_verify_internal_consistency_with_ractor_stored_values def test_verify_internal_consistency_fails_on_foreign_unshareable_store omit "needs GC.verify_internal_consistency with the registered-address check" unless GC.respond_to?(:verify_internal_consistency) && Bug::GC.registered_address_check_enabled? - assert_in_out_err([], <<~RUBY, [], /registered address .* changed since registration to an unshareable object owned by another Ractor/, success: false) + assert_in_out_err([], <<~RUBY, [], /registered address .* changed since registration to an unshareable object owned by another Ractor/, success: false, timeout: 60) require '-test-/gc/register' Bug::GC.register_static(0) port = Ractor::Port.new diff --git a/test/etc/test_etc.rb b/test/etc/test_etc.rb index c2e3af6317ecbb..39cac7c2fae5a0 100644 --- a/test/etc/test_etc.rb +++ b/test/etc/test_etc.rb @@ -131,6 +131,11 @@ def test_uname } end + def test_uname_release_on_windows + release = IO.popen(%w[cmd.exe /c ver], "rb", &:read)[/\d+\.\d+\.\d+/] + assert_equal(release, Etc.uname[:release]) + end if /mswin|mingw/ =~ RUBY_PLATFORM + def test_sysconf begin Etc.sysconf @@ -167,6 +172,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