From 35d5d87540c3262c341c35e974d0d3a53ce30684 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 27 Aug 2015 13:34:10 +0200 Subject: Implement POSIX_MADV_WILLNEED/POSIX_MADV_DONTNEED for newer OSes * autoload.cc (DiscardVirtualMemory): Import. (PrefetchVirtualMemory): Import. * mmap.cc (posix_madvise): Actually implement POSIX_MADV_WILLNEED utilizing PrefetchVirtualMemory and POSIX_MADV_DONTNEED utilizing DiscardVirtualMemory on systems supporting them. * wincap.h (wincaps::has_broken_prefetchvm): New element. * wincap.cc: Implement above element throughout. (wincapc::init): Make sure has_broken_prefetchvm is only true on W10 under WOW64. * include/cygwin/version.h (CYGWIN_VERSION_DLL_MAJOR): Bump to 2003. (CYGWIN_VERSION_API_MINOR): Reset to 0. * new-features.xml (ov-new2.3): New section, document posix_madvise POSIX_MADV_WILLNEED/POSIX_MADV_DONTNEED change. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ChangeLog | 14 +++++ winsup/cygwin/autoload.cc | 2 + winsup/cygwin/include/cygwin/version.h | 4 +- winsup/cygwin/mmap.cc | 110 ++++++++++++++++++++++++++++----- winsup/cygwin/release/2.2.2 | 18 ------ winsup/cygwin/release/2.3.0 | 24 +++++++ winsup/cygwin/wincap.cc | 7 +++ winsup/cygwin/wincap.h | 2 + winsup/doc/ChangeLog | 5 ++ winsup/doc/new-features.xml | 16 +++++ 10 files changed, 165 insertions(+), 37 deletions(-) delete mode 100644 winsup/cygwin/release/2.2.2 create mode 100644 winsup/cygwin/release/2.3.0 diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ba25c1e..c76eb7a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2015-08-27 Corinna Vinschen + + * autoload.cc (DiscardVirtualMemory): Import. + (PrefetchVirtualMemory): Import. + * mmap.cc (posix_madvise): Actually implement POSIX_MADV_WILLNEED + utilizing PrefetchVirtualMemory and POSIX_MADV_DONTNEED utilizing + DiscardVirtualMemory on systems supporting them. + * wincap.h (wincaps::has_broken_prefetchvm): New element. + * wincap.cc: Implement above element throughout. + (wincapc::init): Make sure has_broken_prefetchvm is only true on + W10 under WOW64. + * include/cygwin/version.h (CYGWIN_VERSION_DLL_MAJOR): Bump to 2003. + (CYGWIN_VERSION_API_MINOR): Reset to 0. + 2015-08-26 Corinna Vinschen * fhandler_proc.cc (format_proc_cpuinfo): Only fetch group relations, diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index f9c0f00..0192c6d 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -570,12 +570,14 @@ LoadDLLfunc (GetUdpTable, 12, iphlpapi) LoadDLLfuncEx (CancelSynchronousIo, 4, kernel32, 1) LoadDLLfunc (CreateSymbolicLinkW, 12, kernel32) +LoadDLLfuncEx2 (DiscardVirtualMemory, 8, kernel32, 1, 127) LoadDLLfuncEx (GetLogicalProcessorInformationEx, 12, kernel32, 1) LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1) LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32) LoadDLLfuncEx (IdnToAscii, 20, kernel32, 1) LoadDLLfuncEx (IdnToUnicode, 20, kernel32, 1) LoadDLLfunc (LocaleNameToLCID, 8, kernel32) +LoadDLLfuncEx (PrefetchVirtualMemory, 16, kernel32, 1) LoadDLLfunc (SetThreadGroupAffinity, 12, kernel32) LoadDLLfunc (SetThreadStackGuarantee, 4, kernel32) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 82a0f96..53842ef 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -42,8 +42,8 @@ details. */ the Cygwin shared library". This version is used to track important changes to the DLL and is mainly informative in nature. */ -#define CYGWIN_VERSION_DLL_MAJOR 2002 -#define CYGWIN_VERSION_DLL_MINOR 2 +#define CYGWIN_VERSION_DLL_MAJOR 2003 +#define CYGWIN_VERSION_DLL_MINOR 0 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index cb8b828..984504e 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -1531,35 +1531,111 @@ munlock (const void *addr, size_t len) return ret; } +/* This is required until Mingw-w64 catches up with newer functions. */ +extern "C" WINAPI DWORD DiscardVirtualMemory (PVOID, SIZE_T); + extern "C" int posix_madvise (void *addr, size_t len, int advice) { - int ret; + int ret = 0; /* Check parameters. */ if (advice < POSIX_MADV_NORMAL || advice > POSIX_MADV_DONTNEED || !len) - ret = EINVAL; - else { - /* Check requested memory area. */ - MEMORY_BASIC_INFORMATION m; - char *p = (char *) addr; - char *endp = p + len; - while (p < endp) + ret = EINVAL; + goto out; + } + + /* Check requested memory area. */ + MEMORY_BASIC_INFORMATION m; + char *p, *endp; + + for (p = (char *) addr, endp = p + len; + p < endp; + p = (char *) m.BaseAddress + m.RegionSize) + { + if (!VirtualQuery (p, &m, sizeof m) || m.State == MEM_FREE) { - if (!VirtualQuery (p, &m, sizeof m) || m.State == MEM_FREE) + ret = ENOMEM; + break; + } + } + if (ret) + goto out; + switch (advice) + { + case POSIX_MADV_WILLNEED: + { + /* Align address and length values to page size. */ + size_t pagesize = wincap.allocation_granularity (); + PVOID base = (PVOID) rounddown ((uintptr_t) addr, pagesize); + SIZE_T size = roundup2 (((uintptr_t) addr - (uintptr_t) base) + + len, pagesize); + WIN32_MEMORY_RANGE_ENTRY me = { base, size }; + if (!PrefetchVirtualMemory (GetCurrentProcess (), 1, &me, 0) + && GetLastError () != ERROR_PROC_NOT_FOUND) + { + /* FIXME 2015-08-27: On W10 build 10240 under WOW64, + PrefetchVirtualMemory always returns ERROR_INVALID_PARAMETER + for some reason. If we're running on W10 WOW64, ignore this + error for now. There's an open case at Microsoft for this. */ + if (!wincap.has_broken_prefetchvm () + || GetLastError () != ERROR_INVALID_PARAMETER) + ret = EINVAL; + } + } + break; + case POSIX_MADV_DONTNEED: + { + /* Align address and length values to page size. */ + size_t pagesize = wincap.allocation_granularity (); + PVOID base = (PVOID) rounddown ((uintptr_t) addr, pagesize); + SIZE_T size = roundup2 (((uintptr_t) addr - (uintptr_t) base) + + len, pagesize); + DWORD err = DiscardVirtualMemory (base, size); + /* DiscardVirtualMemory is unfortunately pretty crippled: + On copy-on-write pages it returns ERROR_INVALID_PARAMETER, on + any file-backed memory map it returns ERROR_USER_MAPPED_FILE. + Since POSIX_MADV_DONTNEED is advisory only anyway, let them + slip through. */ + switch (err) + { + case ERROR_PROC_NOT_FOUND: + case ERROR_USER_MAPPED_FILE: + case 0: + break; + case ERROR_INVALID_PARAMETER: { - ret = ENOMEM; - break; + ret = EINVAL; + /* Check if the region contains copy-on-write pages.*/ + for (p = (char *) addr, endp = p + len; + p < endp; + p = (char *) m.BaseAddress + m.RegionSize) + { + if (VirtualQuery (p, &m, sizeof m) + && m.State == MEM_COMMIT + && m.Protect + & (PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY)) + { + /* Yes, let this slip. */ + ret = 0; + break; + } + } } - p = (char *) m.BaseAddress + m.RegionSize; - } - ret = 0; + break; + default: + ret = geterrno_from_win_error (err); + break; + } + } + break; + default: + break; } - +out: syscall_printf ("%d = posix_madvise(%p, %lu, %d)", ret, addr, len, advice); - /* Eventually do nothing. */ - return 0; + return ret; } /* diff --git a/winsup/cygwin/release/2.2.2 b/winsup/cygwin/release/2.2.2 deleted file mode 100644 index baa2d0d..0000000 --- a/winsup/cygwin/release/2.2.2 +++ /dev/null @@ -1,18 +0,0 @@ -What's new: ------------ - - -What changed: -------------- - - -Bug Fixes ---------- - -- Fix a hang when stracing a forking or spawning process without activating - stracing of child processes. - Addresses: https://cygwin.com/ml/cygwin/2015-08/msg00390.html - -- Fix long-standing potential SEGV on 32 bit Cygwin when the dynamic loader - for OS functions fails to load a function on Windows 7 or later. - Addresses: No actual bug report known. diff --git a/winsup/cygwin/release/2.3.0 b/winsup/cygwin/release/2.3.0 new file mode 100644 index 0000000..88b6748 --- /dev/null +++ b/winsup/cygwin/release/2.3.0 @@ -0,0 +1,24 @@ +What's new: +----------- + +- posix_madvise(POSIX_MADV_WILLNEED) now utilizes OS functionality available + starting with Windows 8/Server 2012. Still a no-op on older systems. + +- posix_madvise(POSIX_MADV_DONTNEED) now utilizes OS functionality available + starting with Windows 8.1/Server 2012R2. Still a no-op on older systems. + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix a hang when stracing a forking or spawning process without activating + stracing of child processes. + Addresses: https://cygwin.com/ml/cygwin/2015-08/msg00390.html + +- Fix long-standing potential SEGV on 32 bit Cygwin when the dynamic loader + for OS functions fails to load a function on Windows 7 or later. + Addresses: No actual bug report known. diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 92d47d3..6e98df6 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -50,6 +50,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = { has_set_thread_stack_guarantee:false, has_broken_rtl_query_process_debug_information:false, has_processor_groups:false, + has_broken_prefetchvm:false, }; wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -82,6 +83,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { has_set_thread_stack_guarantee:true, has_broken_rtl_query_process_debug_information:true, has_processor_groups:false, + has_broken_prefetchvm:false, }; wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -114,6 +116,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_set_thread_stack_guarantee:true, has_broken_rtl_query_process_debug_information:false, has_processor_groups:false, + has_broken_prefetchvm:false, }; wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -146,6 +149,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_set_thread_stack_guarantee:true, has_broken_rtl_query_process_debug_information:false, has_processor_groups:true, + has_broken_prefetchvm:false, }; wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -178,6 +182,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_set_thread_stack_guarantee:true, has_broken_rtl_query_process_debug_information:false, has_processor_groups:true, + has_broken_prefetchvm:false, }; wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -210,6 +215,7 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = { has_set_thread_stack_guarantee:true, has_broken_rtl_query_process_debug_information:false, has_processor_groups:true, + has_broken_prefetchvm:true, }; wincapc wincap __attribute__((section (".cygwin_dll_common"), shared)); @@ -281,6 +287,7 @@ wincapc::init () ((wincaps *)caps)->has_restricted_stack_args = false; ((wincaps *)caps)->wow64_has_secondary_stack = false; ((wincaps *)caps)->has_gaa_largeaddress_bug = false; + ((wincaps *)caps)->has_broken_prefetchvm = false; } __small_sprintf (osnam, "NT-%d.%d", version.dwMajorVersion, diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index e4f67bc..26751b1 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -43,6 +43,7 @@ struct wincaps unsigned has_set_thread_stack_guarantee : 1; unsigned has_broken_rtl_query_process_debug_information : 1; unsigned has_processor_groups : 1; + unsigned has_broken_prefetchvm : 1; }; class wincapc @@ -100,6 +101,7 @@ public: bool IMPLEMENT (has_set_thread_stack_guarantee) bool IMPLEMENT (has_broken_rtl_query_process_debug_information) bool IMPLEMENT (has_processor_groups) + bool IMPLEMENT (has_broken_prefetchvm) #undef IMPLEMENT }; diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog index 02061ff..c645c67 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,8 @@ +2015-08-27 Corinna Vinschen + + * new-features.xml (ov-new2.3): New section, document posix_madvise + POSIX_MADV_WILLNEED/POSIX_MADV_DONTNEED change. + 2015-08-18 Jon Turney * faq-using.xml (faq.using.bloda): Add Lavasoft Web Companion to diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index ed8d61d..edd1963 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,6 +4,22 @@ What's new and what changed in Cygwin +What's new and what changed in 2.3 + + + + +posix_madvise(POSIX_MADV_WILLNEED) now utilizes OS functionality available +starting with Windows 8/Server 2012. + +posix_madvise(POSIX_MADV_DONTNEED) now utilizes OS functionality available +starting with Windows 8.1/Server 2012R2. + + + + + + What's new and what changed in 2.2 -- cgit v1.1