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>
|
2015-08-26 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_proc.cc (format_proc_cpuinfo): Only fetch group relations,
|
* fhandler_proc.cc (format_proc_cpuinfo): Only fetch group relations,
|
||||||
|
@ -570,12 +570,14 @@ LoadDLLfunc (GetUdpTable, 12, iphlpapi)
|
|||||||
|
|
||||||
LoadDLLfuncEx (CancelSynchronousIo, 4, kernel32, 1)
|
LoadDLLfuncEx (CancelSynchronousIo, 4, kernel32, 1)
|
||||||
LoadDLLfunc (CreateSymbolicLinkW, 12, kernel32)
|
LoadDLLfunc (CreateSymbolicLinkW, 12, kernel32)
|
||||||
|
LoadDLLfuncEx2 (DiscardVirtualMemory, 8, kernel32, 1, 127)
|
||||||
LoadDLLfuncEx (GetLogicalProcessorInformationEx, 12, kernel32, 1)
|
LoadDLLfuncEx (GetLogicalProcessorInformationEx, 12, kernel32, 1)
|
||||||
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
|
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
|
||||||
LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32)
|
LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32)
|
||||||
LoadDLLfuncEx (IdnToAscii, 20, kernel32, 1)
|
LoadDLLfuncEx (IdnToAscii, 20, kernel32, 1)
|
||||||
LoadDLLfuncEx (IdnToUnicode, 20, kernel32, 1)
|
LoadDLLfuncEx (IdnToUnicode, 20, kernel32, 1)
|
||||||
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
|
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
|
||||||
|
LoadDLLfuncEx (PrefetchVirtualMemory, 16, kernel32, 1)
|
||||||
LoadDLLfunc (SetThreadGroupAffinity, 12, kernel32)
|
LoadDLLfunc (SetThreadGroupAffinity, 12, kernel32)
|
||||||
LoadDLLfunc (SetThreadStackGuarantee, 4, kernel32)
|
LoadDLLfunc (SetThreadStackGuarantee, 4, kernel32)
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ details. */
|
|||||||
the Cygwin shared library". This version is used to track important
|
the Cygwin shared library". This version is used to track important
|
||||||
changes to the DLL and is mainly informative in nature. */
|
changes to the DLL and is mainly informative in nature. */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_DLL_MAJOR 2002
|
#define CYGWIN_VERSION_DLL_MAJOR 2003
|
||||||
#define CYGWIN_VERSION_DLL_MINOR 2
|
#define CYGWIN_VERSION_DLL_MINOR 0
|
||||||
|
|
||||||
/* Major numbers before CYGWIN_VERSION_DLL_EPOCH are
|
/* Major numbers before CYGWIN_VERSION_DLL_EPOCH are
|
||||||
incompatible. */
|
incompatible. */
|
||||||
|
@ -1531,35 +1531,111 @@ munlock (const void *addr, size_t len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is required until Mingw-w64 catches up with newer functions. */
|
||||||
|
extern "C" WINAPI DWORD DiscardVirtualMemory (PVOID, SIZE_T);
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
posix_madvise (void *addr, size_t len, int advice)
|
posix_madvise (void *addr, size_t len, int advice)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
/* Check parameters. */
|
/* Check parameters. */
|
||||||
if (advice < POSIX_MADV_NORMAL || advice > POSIX_MADV_DONTNEED
|
if (advice < POSIX_MADV_NORMAL || advice > POSIX_MADV_DONTNEED
|
||||||
|| !len)
|
|| !len)
|
||||||
ret = EINVAL;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Check requested memory area. */
|
ret = EINVAL;
|
||||||
MEMORY_BASIC_INFORMATION m;
|
goto out;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
syscall_printf ("%d = posix_madvise(%p, %lu, %d)", ret, addr, len, advice);
|
||||||
/* Eventually do nothing. */
|
return ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
What's new:
|
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:
|
What changed:
|
||||||
-------------
|
-------------
|
@ -50,6 +50,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
|||||||
has_set_thread_stack_guarantee:false,
|
has_set_thread_stack_guarantee:false,
|
||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
|
has_broken_prefetchvm:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_set_thread_stack_guarantee:true,
|
||||||
has_broken_rtl_query_process_debug_information:true,
|
has_broken_rtl_query_process_debug_information:true,
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
|
has_broken_prefetchvm:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_set_thread_stack_guarantee:true,
|
||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
|
has_broken_prefetchvm:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_set_thread_stack_guarantee:true,
|
||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
|
has_broken_prefetchvm:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_set_thread_stack_guarantee:true,
|
||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
|
has_broken_prefetchvm:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_set_thread_stack_guarantee:true,
|
||||||
has_broken_rtl_query_process_debug_information:false,
|
has_broken_rtl_query_process_debug_information:false,
|
||||||
has_processor_groups:true,
|
has_processor_groups:true,
|
||||||
|
has_broken_prefetchvm:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
@ -281,6 +287,7 @@ wincapc::init ()
|
|||||||
((wincaps *)caps)->has_restricted_stack_args = false;
|
((wincaps *)caps)->has_restricted_stack_args = false;
|
||||||
((wincaps *)caps)->wow64_has_secondary_stack = false;
|
((wincaps *)caps)->wow64_has_secondary_stack = false;
|
||||||
((wincaps *)caps)->has_gaa_largeaddress_bug = false;
|
((wincaps *)caps)->has_gaa_largeaddress_bug = false;
|
||||||
|
((wincaps *)caps)->has_broken_prefetchvm = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__small_sprintf (osnam, "NT-%d.%d", version.dwMajorVersion,
|
__small_sprintf (osnam, "NT-%d.%d", version.dwMajorVersion,
|
||||||
|
@ -43,6 +43,7 @@ struct wincaps
|
|||||||
unsigned has_set_thread_stack_guarantee : 1;
|
unsigned has_set_thread_stack_guarantee : 1;
|
||||||
unsigned has_broken_rtl_query_process_debug_information : 1;
|
unsigned has_broken_rtl_query_process_debug_information : 1;
|
||||||
unsigned has_processor_groups : 1;
|
unsigned has_processor_groups : 1;
|
||||||
|
unsigned has_broken_prefetchvm : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
@ -100,6 +101,7 @@ public:
|
|||||||
bool IMPLEMENT (has_set_thread_stack_guarantee)
|
bool IMPLEMENT (has_set_thread_stack_guarantee)
|
||||||
bool IMPLEMENT (has_broken_rtl_query_process_debug_information)
|
bool IMPLEMENT (has_broken_rtl_query_process_debug_information)
|
||||||
bool IMPLEMENT (has_processor_groups)
|
bool IMPLEMENT (has_processor_groups)
|
||||||
|
bool IMPLEMENT (has_broken_prefetchvm)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#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>
|
2015-08-18 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
* faq-using.xml (faq.using.bloda): Add Lavasoft Web Companion to
|
* 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>
|
<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>
|
<sect2 id="ov-new2.2"><title>What's new and what changed in 2.2</title>
|
||||||
|
|
||||||
<itemizedlist mark="bullet">
|
<itemizedlist mark="bullet">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user