- Rewrite NtRead/WriteVirtualMemory around MiCopyVirtualMemory, and use MmMapLockedPagesSpecifyCache to do the bulk of the work, instead of the MDL hacks that were previously used.

- Reformat and cleanup the entire file, deprecate NtVirtualLock/Unlock which didn't really work (and aren't really required for any apps for now)
- Major perf optimizations to NtRead/VirtualMemory: Use pool memory transfer when more efficient than MDL, and use local stack buffer when size permits.
- This patch provides up to 109% improvement (more than twice as fast) in certain virtual memory operations.
- Thanks to Alex for researching this issue, and providing the internal information on the various optimizations and behaviors the NT implementation uses.

svn path=/trunk/; revision=33133
This commit is contained in:
Aleksey Bragin 2008-04-24 21:26:01 +00:00
parent 4b3ff92f36
commit d136b969cf
2 changed files with 886 additions and 758 deletions

View file

@ -25,6 +25,9 @@
/* FUNCTIONS ******************************************************************/
/*
* @implemented
*/
LONG
FASTCALL
InterlockedIncrement(IN LONG volatile *Addend)
@ -35,6 +38,9 @@ InterlockedIncrement(IN LONG volatile *Addend)
return _InterlockedIncrement(Addend);
}
/*
* @implemented
*/
LONG
FASTCALL
InterlockedDecrement(IN LONG volatile *Addend)
@ -45,6 +51,9 @@ InterlockedDecrement(IN LONG volatile *Addend)
return _InterlockedDecrement(Addend);
}
/*
* @implemented
*/
LONG
FASTCALL
InterlockedCompareExchange(IN OUT LONG volatile *Destination,
@ -57,6 +66,9 @@ InterlockedCompareExchange(IN OUT LONG volatile *Destination,
return _InterlockedCompareExchange(Destination, Exchange, Comperand);
}
/*
* @implemented
*/
LONG
FASTCALL
InterlockedExchange(IN OUT LONG volatile *Destination,
@ -68,6 +80,9 @@ InterlockedExchange(IN OUT LONG volatile *Destination,
return _InterlockedExchange(Destination, Value);
}
/*
* @implemented
*/
LONG
FASTCALL
InterlockedExchangeAdd(IN OUT LONG volatile *Addend,
@ -78,3 +93,89 @@ InterlockedExchangeAdd(IN OUT LONG volatile *Addend,
//
return _InterlockedExchangeAdd(Addend, Increment);
}
/*
* @implemented
*/
VOID
NTAPI
ProbeForRead(IN CONST VOID *Address,
IN ULONG Length,
IN ULONG Alignment)
{
PAGED_CODE();
/* Only probe if we have a valid length */
if (Length != 0)
{
/* Sanity check */
ASSERT((Alignment == 1) ||
(Alignment == 2) ||
(Alignment == 4) ||
(Alignment == 8) ||
(Alignment == 16));
/* Check for correct alignment */
if (((ULONG_PTR)Address & (Alignment - 1)) != 0)
{
/* Incorrect alignment */
ExRaiseDatatypeMisalignment();
}
else if (((ULONG_PTR)Address + Length) < (ULONG_PTR)Address ||
((ULONG_PTR)Address + Length) > (ULONG_PTR)MmUserProbeAddress)
{
/* Attempt a read */
*(volatile CHAR* const)MmUserProbeAddress = 0;
}
}
}
/*
* @implemented
*/
VOID
NTAPI
ProbeForWrite(IN PVOID Address,
IN ULONG Length,
IN ULONG Alignment)
{
ULONG_PTR Last, Current = (ULONG_PTR)Address;
PAGED_CODE();
/* Only probe if we have a valid length */
if (Length != 0)
{
/* Sanity check */
ASSERT((Alignment == 1) ||
(Alignment == 2) ||
(Alignment == 4) ||
(Alignment == 8) ||
(Alignment == 16));
/* Check the alignment */
if ((Current & (Alignment - 1)) != 0)
{
/* Incorrect alignment */
ExRaiseDatatypeMisalignment();
}
/* Get the end address */
Last = Current + Length - 1;
if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress))
{
/* Raise an access violation */
ExRaiseAccessViolation();
}
/* Round down to the last page */
Last = PAGE_ROUND_DOWN(Last) + PAGE_SIZE;
do
{
/* Attempt a write */
*(volatile CHAR*)Current = *(volatile CHAR*)Current;
/* Go to the next address */
Current = PAGE_ROUND_DOWN(Current) + PAGE_SIZE;
} while (Current != Last);
}
}

File diff suppressed because it is too large Load diff