diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2015-08-27 14:34:10 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2015-08-27 14:34:25 +0300 |
commit | 35d5d87540c3262c341c35e974d0d3a53ce30684 (patch) | |
tree | 8899a534e97890ea8167f2448f1782d06c4f09f9 | |
parent | e6d9af11f1f21a70a6d947ab452ac4d82caace64 (diff) |
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 <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/ChangeLog | 14 | ||||
-rw-r--r-- | winsup/cygwin/autoload.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/mmap.cc | 110 | ||||
-rw-r--r-- | winsup/cygwin/release/2.3.0 (renamed from winsup/cygwin/release/2.2.2) | 6 | ||||
-rw-r--r-- | winsup/cygwin/wincap.cc | 7 | ||||
-rw-r--r-- | winsup/cygwin/wincap.h | 2 | ||||
-rw-r--r-- | winsup/doc/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/doc/new-features.xml | 16 |
9 files changed, 147 insertions, 19 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ba25c1e33..c76eb7a5f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2015-08-27 Corinna Vinschen <corinna@vinschen.de> + + * 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 <corinna@vinschen.de> * fhandler_proc.cc (format_proc_cpuinfo): Only fetch group relations, diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index f9c0f00cb..0192c6d64 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 82a0f96df..53842efb8 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 cb8b8284e..984504ede 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.3.0 index baa2d0dd3..88b67487f 100644 --- a/winsup/cygwin/release/2.2.2 +++ b/winsup/cygwin/release/2.3.0 @@ -1,6 +1,12 @@ 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: ------------- diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 92d47d367..6e98df6c4 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 e4f67bcef..26751b18e 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 02061ff87..c645c670d 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,8 @@ +2015-08-27 Corinna Vinschen <corinna@vinschen.de> + + * new-features.xml (ov-new2.3): New section, document posix_madvise + POSIX_MADV_WILLNEED/POSIX_MADV_DONTNEED change. + 2015-08-18 Jon Turney <jon.turney@dronecode.org.uk> * 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 ed8d61d3a..edd19633f 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,6 +4,22 @@ <sect1 id="ov-new"><title>What's new and what changed in Cygwin</title> +<sect2 id="ov-new2.3"><title>What's new and what changed in 2.3</title> + +<itemizedlist mark="bullet"> + +<listitem><para> +posix_madvise(POSIX_MADV_WILLNEED) now utilizes OS functionality available +starting with Windows 8/Server 2012. +</para><para> +posix_madvise(POSIX_MADV_DONTNEED) now utilizes OS functionality available +starting with Windows 8.1/Server 2012R2. +</para></listitem> + +</itemizedlist> + +</sect2> + <sect2 id="ov-new2.2"><title>What's new and what changed in 2.2</title> <itemizedlist mark="bullet"> |