* autoload.cc (NtLockVirtualMemory): Import.

(NtUnlockVirtualMemory): Import.
	(GetProcessWorkingSetSize): Import.
	(SetProcessWorkingSetSize): Import.
	* cygwin.din (mlock): Export.
	(munlock): Export.
	* mmap.cc (mlock): New function.
	(munlock): Ditto.
	* ntdll.h (STATUS_WORKING_SET_QUOTA): Define.
	(LOCK_VM_IN_WSL): Define.
	(LOCK_VM_IN_RAM): Define.
	(NtLockVirtualMemory): Declare.
	(NtUnlockVirtualMemory): Declare.
	* sysconf.cc (sysconf): Implement _SC_MEMLOCK_RANGE.
	* wincap.h: Implement has_working_virtual_lock throughout.
	* wincap.cc: Ditto.
	* include/cygwin/version.h: Bump API minor version.
	* include/sys/mman.h (mlock): Declare,
	(munlock): Declare.
This commit is contained in:
Corinna Vinschen 2005-10-18 18:51:33 +00:00
parent a92822b747
commit 1f5c3042d5
10 changed files with 160 additions and 14 deletions

View File

@ -1,3 +1,25 @@
2005-10-18 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (NtLockVirtualMemory): Import.
(NtUnlockVirtualMemory): Import.
(GetProcessWorkingSetSize): Import.
(SetProcessWorkingSetSize): Import.
* cygwin.din (mlock): Export.
(munlock): Export.
* mmap.cc (mlock): New function.
(munlock): Ditto.
* ntdll.h (STATUS_WORKING_SET_QUOTA): Define.
(LOCK_VM_IN_WSL): Define.
(LOCK_VM_IN_RAM): Define.
(NtLockVirtualMemory): Declare.
(NtUnlockVirtualMemory): Declare.
* sysconf.cc (sysconf): Implement _SC_MEMLOCK_RANGE.
* wincap.h: Implement has_working_virtual_lock throughout.
* wincap.cc: Ditto.
* include/cygwin/version.h: Bump API minor version.
* include/sys/mman.h (mlock): Declare,
(munlock): Declare.
2005-10-18 Christopher Faylor <cgf@timesys.com> 2005-10-18 Christopher Faylor <cgf@timesys.com>
* sigproc.cc (child_info::sync): Use correct name when closing to * sigproc.cc (child_info::sync): Use correct name when closing to

View File

@ -379,6 +379,7 @@ LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
LoadDLLfuncEx (NtCreateFile, 44, ntdll, 1) LoadDLLfuncEx (NtCreateFile, 44, ntdll, 1)
LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1) LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
LoadDLLfuncEx (NtLockVirtualMemory, 16, ntdll, 1)
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1) LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1) LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1) LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
@ -390,6 +391,7 @@ LoadDLLfuncEx (NtQuerySecurityObject, 20, ntdll, 1)
LoadDLLfuncEx (NtQueryVirtualMemory, 24, ntdll, 1) LoadDLLfuncEx (NtQueryVirtualMemory, 24, ntdll, 1)
LoadDLLfuncEx (NtQueryVolumeInformationFile, 20, ntdll, 1) LoadDLLfuncEx (NtQueryVolumeInformationFile, 20, ntdll, 1)
LoadDLLfuncEx (NtSetSecurityObject, 12, ntdll, 1) LoadDLLfuncEx (NtSetSecurityObject, 12, ntdll, 1)
LoadDLLfuncEx (NtUnlockVirtualMemory, 16, ntdll, 1)
LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1) LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1) LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1) LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
@ -508,6 +510,7 @@ LoadDLLfuncEx2 (GetCompressedFileSizeA, 8, kernel32, 1, 0xffffffff)
LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1) LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1)
LoadDLLfuncEx (GetDiskFreeSpaceEx, 16, kernel32, 1) LoadDLLfuncEx (GetDiskFreeSpaceEx, 16, kernel32, 1)
LoadDLLfuncEx (GetNativeSystemInfo, 4, kernel32, 1) LoadDLLfuncEx (GetNativeSystemInfo, 4, kernel32, 1)
LoadDLLfuncEx (GetProcessWorkingSetSize, 12, kernel32, 1)
LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1) LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1)
LoadDLLfuncEx (GetVolumeNameForVolumeMountPointA, 12, kernel32, 1) LoadDLLfuncEx (GetVolumeNameForVolumeMountPointA, 12, kernel32, 1)
LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1) LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1)
@ -516,6 +519,7 @@ LoadDLLfuncEx (IsWow64Process, 8, kernel32, 1);
LoadDLLfuncEx (Process32First, 8, kernel32, 1) LoadDLLfuncEx (Process32First, 8, kernel32, 1)
LoadDLLfuncEx (Process32Next, 8, kernel32, 1) LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
LoadDLLfuncEx (RegisterServiceProcess, 8, kernel32, 1) LoadDLLfuncEx (RegisterServiceProcess, 8, kernel32, 1)
LoadDLLfuncEx (SetProcessWorkingSetSize, 12, kernel32, 1)
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1) LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
LoadDLLfuncEx (SwitchToThread, 0, kernel32, 1) LoadDLLfuncEx (SwitchToThread, 0, kernel32, 1)

View File

@ -953,6 +953,8 @@ _modff = modff NOSIGFE
mount SIGFE mount SIGFE
_mount = mount SIGFE _mount = mount SIGFE
mprotect SIGFE mprotect SIGFE
mlock SIGFE
munlock SIGFE
mrand48 NOSIGFE mrand48 NOSIGFE
msgctl SIGFE msgctl SIGFE
msgget SIGFE msgget SIGFE

View File

@ -277,12 +277,13 @@ details. */
138: Export readdir_r. 138: Export readdir_r.
139: Start using POSIX definition of struct msghdr and WinSock2 139: Start using POSIX definition of struct msghdr and WinSock2
IPPROTO_IP values. IPPROTO_IP values.
140: Export mlock, munlock.
*/ */
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 139 #define CYGWIN_VERSION_API_MINOR 140
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -49,6 +49,8 @@ extern void *mmap (void *__addr, size_t __len, int __prot, int __flags, int __fd
extern int munmap (void *__addr, size_t __len); extern int munmap (void *__addr, size_t __len);
extern int mprotect (void *__addr, size_t __len, int __prot); extern int mprotect (void *__addr, size_t __len, int __prot);
extern int msync (void *__addr, size_t __len, int __flags); extern int msync (void *__addr, size_t __len, int __flags);
extern int mlock (const void *__addr, size_t __len);
extern int munlock (const void *__addr, size_t __len);
#ifdef __cplusplus #ifdef __cplusplus
}; };

View File

@ -977,6 +977,98 @@ mprotect (void *addr, size_t len, int prot)
return 0; return 0;
} }
extern "C" int
mlock (const void *addr, size_t len)
{
if (!wincap.has_working_virtual_lock ())
return 0;
int ret = -1;
/* Instead of using VirtualLock, which does not guarantee that the pages
aren't swapped out when the process is inactive, we're using
ZwLockVirtualMemory with the LOCK_VM_IN_RAM flag to do what mlock on
POSIX systems does. On NT, this requires SeLockMemoryPrivilege,
which is given only to SYSTEM by default. */
push_thread_privilege (SE_LOCK_MEMORY_PRIV, true);
/* Align address and length values to page size. */
PVOID base = (PVOID) ((uintptr_t) addr & ~(getpagesize () - 1));
ULONG size = ((uintptr_t) addr - (uintptr_t) base) + len;
size = (size + getpagesize () - 1) & ~(getpagesize () - 1);
NTSTATUS status = 0;
do
{
status = NtLockVirtualMemory (hMainProc, &base, &size, LOCK_VM_IN_RAM);
if (status == STATUS_WORKING_SET_QUOTA)
{
/* The working set is too small, try to increase it so that the
requested locking region fits in. Unfortunately I don't know
any function which would return the currently locked pages of
a process (no go with NtQueryVirtualMemory).
So, except for the border cases, what we do here is something
really embarrassing. We raise the working set by 64K at a time
and retry, until either we fail to raise the working set size
further, or until NtLockVirtualMemory returns successfully (or
with another error). */
ULONG min, max;
if (!GetProcessWorkingSetSize (hMainProc, &min, &max))
{
set_errno (ENOMEM);
break;
}
if (min < size)
min = size + 12 * getpagesize (); /* Evaluated by testing */
else if (size < 65536)
min += size;
else
min += 65536;
if (max < min)
max = min;
if (!SetProcessWorkingSetSize (hMainProc, min, max))
{
set_errno (ENOMEM);
break;
}
}
else if (!NT_SUCCESS (status))
__seterrno_from_nt_status (status);
else
ret = 0;
}
while (status == STATUS_WORKING_SET_QUOTA);
pop_thread_privilege ();
return ret;
}
extern "C" int
munlock (const void *addr, size_t len)
{
if (!wincap.has_working_virtual_lock ())
return 0;
int ret = -1;
push_thread_privilege (SE_LOCK_MEMORY_PRIV, true);
PVOID base = (PVOID) addr;
ULONG size = len;
NTSTATUS status = NtUnlockVirtualMemory (hMainProc, &base, &size,
LOCK_VM_IN_RAM);
if (!NT_SUCCESS (status))
__seterrno_from_nt_status (status);
else
ret = 0;
pop_thread_privilege ();
return ret;
}
/* /*
* Base implementation: * Base implementation:
* *

View File

@ -10,6 +10,7 @@
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023)
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1L)
#define PDI_MODULES 0x01 #define PDI_MODULES 0x01
#define PDI_HEAPS 0x04 #define PDI_HEAPS 0x04
#define LDRP_IMAGE_DLL 0x00000004 #define LDRP_IMAGE_DLL 0x00000004
@ -25,6 +26,9 @@
#define AT_ROUND_TO_PAGE 0x40000000 #define AT_ROUND_TO_PAGE 0x40000000
#define LOCK_VM_IN_WSL 1
#define LOCK_VM_IN_RAM 2
typedef ULONG KAFFINITY; typedef ULONG KAFFINITY;
typedef enum _SYSTEM_INFORMATION_CLASS typedef enum _SYSTEM_INFORMATION_CLASS
@ -480,6 +484,7 @@ extern "C"
PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER, PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL, PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL,
PTOKEN_SOURCE); PTOKEN_SOURCE);
NTSTATUS NTAPI NtLockVirtualMemory (HANDLE, PVOID *, ULONG *, ULONG);
NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG, NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
PLARGE_INTEGER, PULONG, SECTION_INHERIT, PLARGE_INTEGER, PULONG, SECTION_INHERIT,
ULONG, ULONG); ULONG, ULONG);
@ -503,6 +508,7 @@ extern "C"
FS_INFORMATION_CLASS); FS_INFORMATION_CLASS);
NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION, NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR); PSECURITY_DESCRIPTOR);
NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, ULONG *, ULONG);
NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID); NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR); VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
ULONG NTAPI RtlNtStatusToDosError (NTSTATUS); ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);

View File

@ -123,6 +123,8 @@ sysconf (int in)
return RTSIG_MAX; return RTSIG_MAX;
case _SC_TTY_NAME_MAX: case _SC_TTY_NAME_MAX:
return TTY_NAME_MAX; return TTY_NAME_MAX;
case _SC_MEMLOCK_RANGE:
return _POSIX_MEMLOCK_RANGE;
} }
/* Invalid input or unimplemented sysconf name */ /* Invalid input or unimplemented sysconf name */

View File

@ -60,7 +60,8 @@ static NO_COPY wincaps wincap_unknown = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false, has_null_console_handler_routine:false,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:false
}; };
static NO_COPY wincaps wincap_95 = { static NO_COPY wincaps wincap_95 = {
@ -112,7 +113,8 @@ static NO_COPY wincaps wincap_95 = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false, has_null_console_handler_routine:false,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:false
}; };
static NO_COPY wincaps wincap_95osr2 = { static NO_COPY wincaps wincap_95osr2 = {
@ -164,7 +166,8 @@ static NO_COPY wincaps wincap_95osr2 = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false, has_null_console_handler_routine:false,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:false
}; };
static NO_COPY wincaps wincap_98 = { static NO_COPY wincaps wincap_98 = {
@ -216,7 +219,8 @@ static NO_COPY wincaps wincap_98 = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false, has_null_console_handler_routine:false,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:false
}; };
static NO_COPY wincaps wincap_98se = { static NO_COPY wincaps wincap_98se = {
@ -268,7 +272,8 @@ static NO_COPY wincaps wincap_98se = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false, has_null_console_handler_routine:false,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:false
}; };
static NO_COPY wincaps wincap_me = { static NO_COPY wincaps wincap_me = {
@ -320,7 +325,8 @@ static NO_COPY wincaps wincap_me = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:true, detect_win16_exe:true,
has_null_console_handler_routine:false, has_null_console_handler_routine:false,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:false
}; };
static NO_COPY wincaps wincap_nt3 = { static NO_COPY wincaps wincap_nt3 = {
@ -372,7 +378,8 @@ static NO_COPY wincaps wincap_nt3 = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:true
}; };
static NO_COPY wincaps wincap_nt4 = { static NO_COPY wincaps wincap_nt4 = {
@ -424,7 +431,8 @@ static NO_COPY wincaps wincap_nt4 = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:true
}; };
static NO_COPY wincaps wincap_nt4sp4 = { static NO_COPY wincaps wincap_nt4sp4 = {
@ -476,7 +484,8 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_guid_volumes:false, has_guid_volumes:false,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:true
}; };
static NO_COPY wincaps wincap_2000 = { static NO_COPY wincaps wincap_2000 = {
@ -528,7 +537,8 @@ static NO_COPY wincaps wincap_2000 = {
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:false has_disk_ex_ioctls:false,
has_working_virtual_lock:true
}; };
static NO_COPY wincaps wincap_xp = { static NO_COPY wincaps wincap_xp = {
@ -580,7 +590,8 @@ static NO_COPY wincaps wincap_xp = {
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:true has_disk_ex_ioctls:true,
has_working_virtual_lock:true
}; };
static NO_COPY wincaps wincap_2003 = { static NO_COPY wincaps wincap_2003 = {
@ -632,7 +643,8 @@ static NO_COPY wincaps wincap_2003 = {
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:true has_disk_ex_ioctls:true,
has_working_virtual_lock:true
}; };
static NO_COPY wincaps wincap_vista = { static NO_COPY wincaps wincap_vista = {
@ -684,7 +696,8 @@ static NO_COPY wincaps wincap_vista = {
has_guid_volumes:true, has_guid_volumes:true,
detect_win16_exe:false, detect_win16_exe:false,
has_null_console_handler_routine:true, has_null_console_handler_routine:true,
has_disk_ex_ioctls:true has_disk_ex_ioctls:true,
has_working_virtual_lock:true
}; };
wincapc wincap; wincapc wincap;

View File

@ -62,6 +62,7 @@ struct wincaps
unsigned detect_win16_exe : 1; unsigned detect_win16_exe : 1;
unsigned has_null_console_handler_routine : 1; unsigned has_null_console_handler_routine : 1;
unsigned has_disk_ex_ioctls : 1; unsigned has_disk_ex_ioctls : 1;
unsigned has_working_virtual_lock : 1;
}; };
class wincapc class wincapc
@ -128,6 +129,7 @@ public:
bool IMPLEMENT (detect_win16_exe) bool IMPLEMENT (detect_win16_exe)
bool IMPLEMENT (has_null_console_handler_routine) bool IMPLEMENT (has_null_console_handler_routine)
bool IMPLEMENT (has_disk_ex_ioctls) bool IMPLEMENT (has_disk_ex_ioctls)
bool IMPLEMENT (has_working_virtual_lock)
#undef IMPLEMENT #undef IMPLEMENT
}; };