mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
- 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:
parent
4b3ff92f36
commit
d136b969cf
2 changed files with 886 additions and 758 deletions
|
@ -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
Loading…
Reference in a new issue