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>
This commit is contained in:
parent
e6d9af11f1
commit
35d5d87540
@ -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,
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
{
|
||||
if (!VirtualQuery (p, &m, sizeof m) || m.State == MEM_FREE)
|
||||
{
|
||||
ret = ENOMEM;
|
||||
break;
|
||||
}
|
||||
p = (char *) m.BaseAddress + m.RegionSize;
|
||||
}
|
||||
ret = 0;
|
||||
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)
|
||||
{
|
||||
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 = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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:
|
||||
-------------
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user