[RTL/NTOSKRNL]

- Seperate some usermode only heap functions into their own file and implement dummys in the kernel rtl so that they don't get included in the kernel
- Convert usage of RTL_CRITICAL_SECTION in heappage.c to use of HEAP_LOCK
- Implement A kernel dummy for RtlCallVectoredExceptionHandlers, so we don't put vectored exception handler code into ntoskrnl
- Now we don't have critical section code in the kernel anymore, which wasn't working anyway.

svn path=/trunk/; revision=58173
This commit is contained in:
Timo Kreuzer 2013-01-14 09:35:50 +00:00
parent 70ff0357a0
commit 69bc32e0f6
8 changed files with 194 additions and 138 deletions

View file

@ -80,7 +80,7 @@ ULONG LdrpActiveUnloadCount;
VOID RtlpInitializeVectoredExceptionHandling(VOID);
VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
VOID RtlInitializeHeapManager(VOID);
VOID NTAPI RtlInitializeHeapManager(VOID);
extern BOOLEAN RtlpPageHeapEnabled;
ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c

View file

@ -30,6 +30,7 @@ list(APPEND SOURCE
heap.c
heapdbg.c
heappage.c
heapuser.c
image.c
interlck.c
message.c

View file

@ -23,8 +23,6 @@
#define NDEBUG
#include <debug.h>
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
/* Bitmaps stuff */
/* How many least significant bits are clear */
@ -966,98 +964,6 @@ RtlpDestroyHeapSegment(PHEAP_SEGMENT Segment)
}
}
/* Usermode only! */
VOID NTAPI
RtlpAddHeapToProcessList(PHEAP Heap)
{
PPEB Peb;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
//_SEH2_TRY {
/* Check if max number of heaps reached */
if (Peb->NumberOfHeaps == Peb->MaximumNumberOfHeaps)
{
// TODO: Handle this case
ASSERT(FALSE);
}
/* Add the heap to the process heaps */
Peb->ProcessHeaps[Peb->NumberOfHeaps] = Heap;
Peb->NumberOfHeaps++;
Heap->ProcessHeapsListIndex = (USHORT)Peb->NumberOfHeaps;
// } _SEH2_FINALLY {
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
// } _SEH2_END
}
/* Usermode only! */
VOID NTAPI
RtlpRemoveHeapFromProcessList(PHEAP Heap)
{
PPEB Peb;
PHEAP *Current, *Next;
ULONG Count;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
/* Check if we don't need anything to do */
if ((Heap->ProcessHeapsListIndex == 0) ||
(Heap->ProcessHeapsListIndex > Peb->NumberOfHeaps) ||
(Peb->NumberOfHeaps == 0))
{
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
return;
}
/* The process actually has more than one heap.
Use classic, lernt from university times algorithm for removing an entry
from a static array */
Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
Next = Current + 1;
/* How many items we need to shift to the left */
Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);
/* Move them all in a loop */
while (--Count)
{
/* Copy it and advance next pointer */
*Current = *Next;
/* Update its index */
(*Current)->ProcessHeapsListIndex -= 1;
/* Advance pointers */
Current++;
Next++;
}
/* Decrease total number of heaps */
Peb->NumberOfHeaps--;
/* Zero last unused item */
Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
Heap->ProcessHeapsListIndex = 0;
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
}
PHEAP_FREE_ENTRY NTAPI
RtlpCoalesceHeap(PHEAP Heap)
{
@ -3685,22 +3591,6 @@ BOOLEAN NTAPI RtlValidateHeap(
return HeapValid;
}
VOID
RtlInitializeHeapManager(VOID)
{
PPEB Peb;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Initialize heap-related fields of PEB */
Peb->NumberOfHeaps = 0;
/* Initialize the process heaps list protecting lock */
RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
}
/*
* @implemented
*/

View file

@ -467,4 +467,16 @@ RtlpPageHeapSize(HANDLE HeapPtr,
ULONG Flags,
PVOID Ptr);
VOID
NTAPI
RtlpAddHeapToProcessList(PHEAP Heap);
VOID
NTAPI
RtlpRemoveHeapFromProcessList(PHEAP Heap);
VOID
NTAPI
RtlInitializeHeapManager(VOID);
#endif

View file

@ -61,7 +61,7 @@ typedef struct _DPH_HEAP_ROOT
{
ULONG Signature;
ULONG HeapFlags;
PRTL_CRITICAL_SECTION HeapCritSect;
PHEAP_LOCK HeapCritSect;
ULONG nRemoteLockAcquired;
PDPH_HEAP_BLOCK pVirtualStorageListHead;
@ -110,11 +110,11 @@ WCHAR RtlpDphTargetDlls[512];
LIST_ENTRY RtlpDphPageHeapList;
BOOLEAN RtlpDphPageHeapListInitialized;
RTL_CRITICAL_SECTION RtlpDphPageHeapListLock;
PHEAP_LOCK RtlpDphPageHeapListLock;
ULONG RtlpDphPageHeapListLength;
UNICODE_STRING RtlpDphTargetDllsUnicode;
RTL_CRITICAL_SECTION RtlpDphDelayedFreeQueueLock;
PHEAP_LOCK RtlpDphDelayedFreeQueueLock;
LIST_ENTRY RtlpDphDelayedFreeQueue;
SLIST_HEADER RtlpDphDelayedTemporaryPushList;
SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks;
@ -234,7 +234,7 @@ RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
if (Flags & HEAP_NO_SERIALIZE)
{
/* More complex scenario */
if (!RtlTryEnterCriticalSection(DphRoot->HeapCritSect))
if (!RtlEnterHeapLock(DphRoot->HeapCritSect, TRUE))
{
if (!DphRoot->nRemoteLockAcquired)
{
@ -246,13 +246,13 @@ RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
}
/* Enter the heap's critical section */
RtlEnterCriticalSection(DphRoot->HeapCritSect);
RtlEnterHeapLock(DphRoot->HeapCritSect, TRUE);
}
}
else
{
/* Just enter the heap's critical section */
RtlEnterCriticalSection(DphRoot->HeapCritSect);
RtlEnterHeapLock(DphRoot->HeapCritSect, TRUE);
}
}
@ -260,7 +260,7 @@ VOID NTAPI
RtlpDphLeaveCriticalSection(PDPH_HEAP_ROOT DphRoot)
{
/* Just leave the heap's critical section */
RtlLeaveCriticalSection(DphRoot->HeapCritSect);
RtlLeaveHeapLock(DphRoot->HeapCritSect);
}
@ -1161,7 +1161,7 @@ RtlpDphInitializeDelayedFreeQueue()
{
NTSTATUS Status;
Status = RtlInitializeCriticalSection(&RtlpDphDelayedFreeQueueLock);
Status = RtlInitializeHeapLock(&RtlpDphDelayedFreeQueueLock);
if (!NT_SUCCESS(Status))
{
// TODO: Log this error!
@ -1192,7 +1192,7 @@ RtlpDphFreeDelayedBlocksFromHeap(PDPH_HEAP_ROOT DphRoot,
then it releases the lock and frees the blocks. But let's make it simple for now */
/* Acquire the delayed free queue lock */
RtlEnterCriticalSection(&RtlpDphDelayedFreeQueueLock);
RtlEnterHeapLock(RtlpDphDelayedFreeQueueLock, TRUE);
/* Traverse the list */
Current = RtlpDphDelayedFreeQueue.Flink;
@ -1230,7 +1230,7 @@ RtlpDphFreeDelayedBlocksFromHeap(PDPH_HEAP_ROOT DphRoot,
}
/* Release the delayed free queue lock */
RtlLeaveCriticalSection(&RtlpDphDelayedFreeQueueLock);
RtlLeaveHeapLock(RtlpDphDelayedFreeQueueLock);
}
NTSTATUS NTAPI
@ -1391,7 +1391,7 @@ RtlpDphProcessStartupInitialization()
/* Initialize the DPH heap list and its critical section */
InitializeListHead(&RtlpDphPageHeapList);
Status = RtlInitializeCriticalSection(&RtlpDphPageHeapListLock);
Status = RtlInitializeHeapLock(&RtlpDphPageHeapListLock);
if (!NT_SUCCESS(Status))
{
ASSERT(FALSE);
@ -1485,13 +1485,12 @@ RtlpPageHeapCreate(ULONG Flags,
/* Initialize the DPH root */
DphRoot->Signature = DPH_SIGNATURE;
DphRoot->HeapFlags = Flags;
DphRoot->HeapCritSect = (PRTL_CRITICAL_SECTION)((PCHAR)DphRoot + DPH_POOL_SIZE);
DphRoot->ExtraFlags = RtlpDphGlobalFlags;
ZwQueryPerformanceCounter(&PerfCounter, NULL);
DphRoot->Seed = PerfCounter.LowPart;
RtlInitializeCriticalSection(DphRoot->HeapCritSect);
RtlInitializeHeapLock(&DphRoot->HeapCritSect);
InitializeListHead(&DphRoot->AvailableAllocationHead);
/* Create a normal heap for this paged heap */
@ -1539,7 +1538,7 @@ RtlpPageHeapCreate(ULONG Flags,
if (!RtlpDphPageHeapListInitialized) RtlpDphProcessStartupInitialization();
/* Acquire the heap list lock */
RtlEnterCriticalSection(&RtlpDphPageHeapListLock);
RtlEnterHeapLock(RtlpDphPageHeapListLock, TRUE);
/* Insert this heap to the tail of the global list */
InsertTailList(&RtlpDphPageHeapList, &DphRoot->NextHeap);
@ -1548,7 +1547,7 @@ RtlpPageHeapCreate(ULONG Flags,
RtlpDphPageHeapListLength++;
/* Release the heap list lock */
RtlLeaveCriticalSection(&RtlpDphPageHeapListLock);
RtlLeaveHeapLock(RtlpDphPageHeapListLock);
if (RtlpDphDebugOptions & DPH_DEBUG_VERBOSE)
{
@ -1611,18 +1610,18 @@ RtlpPageHeapDestroy(HANDLE HeapPtr)
}
/* Acquire the global heap list lock */
RtlEnterCriticalSection(&RtlpDphPageHeapListLock);
RtlEnterHeapLock(RtlpDphPageHeapListLock, TRUE);
/* Remove the entry and decrement the global counter */
RemoveEntryList(&DphRoot->NextHeap);
RtlpDphPageHeapListLength--;
/* Release the global heap list lock */
RtlLeaveCriticalSection(&RtlpDphPageHeapListLock);
RtlLeaveHeapLock(RtlpDphPageHeapListLock);
/* Leave and delete this heap's critical section */
RtlLeaveCriticalSection(DphRoot->HeapCritSect);
RtlDeleteCriticalSection(DphRoot->HeapCritSect);
RtlLeaveHeapLock(DphRoot->HeapCritSect);
RtlDeleteHeapLock(DphRoot->HeapCritSect);
/* Now go through all virtual list nodes and release the VM */
Node = DphRoot->pVirtualStorageListHead;

128
reactos/lib/rtl/heapuser.c Normal file
View file

@ -0,0 +1,128 @@
/* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/rtl/heap.c
* PURPOSE: RTL Heap backend allocator (user mode only functions)
* PROGRAMMERS: Copyright 2010 Aleksey Bragin
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#include <heap.h>
#define NDEBUG
#include <debug.h>
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
/* Usermode only! */
VOID
NTAPI
RtlpAddHeapToProcessList(PHEAP Heap)
{
PPEB Peb;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
//_SEH2_TRY {
/* Check if max number of heaps reached */
if (Peb->NumberOfHeaps == Peb->MaximumNumberOfHeaps)
{
// TODO: Handle this case
ASSERT(FALSE);
}
/* Add the heap to the process heaps */
Peb->ProcessHeaps[Peb->NumberOfHeaps] = Heap;
Peb->NumberOfHeaps++;
Heap->ProcessHeapsListIndex = (USHORT)Peb->NumberOfHeaps;
// } _SEH2_FINALLY {
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
// } _SEH2_END
}
/* Usermode only! */
VOID
NTAPI
RtlpRemoveHeapFromProcessList(PHEAP Heap)
{
PPEB Peb;
PHEAP *Current, *Next;
ULONG Count;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
/* Check if we don't need anything to do */
if ((Heap->ProcessHeapsListIndex == 0) ||
(Heap->ProcessHeapsListIndex > Peb->NumberOfHeaps) ||
(Peb->NumberOfHeaps == 0))
{
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
return;
}
/* The process actually has more than one heap.
Use classic, lernt from university times algorithm for removing an entry
from a static array */
Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
Next = Current + 1;
/* How many items we need to shift to the left */
Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);
/* Move them all in a loop */
while (--Count)
{
/* Copy it and advance next pointer */
*Current = *Next;
/* Update its index */
(*Current)->ProcessHeapsListIndex -= 1;
/* Advance pointers */
Current++;
Next++;
}
/* Decrease total number of heaps */
Peb->NumberOfHeaps--;
/* Zero last unused item */
Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
Heap->ProcessHeapsListIndex = 0;
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
}
VOID
NTAPI
RtlInitializeHeapManager(VOID)
{
PPEB Peb;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Initialize heap-related fields of PEB */
Peb->NumberOfHeaps = 0;
/* Initialize the process heaps list protecting lock */
RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
}

View file

@ -74,15 +74,11 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
ULONG_PTR StackLow, StackHigh;
ULONG_PTR RegistrationFrameEnd;
/* Perform vectored exception handling if we are in user mode */
if (RtlpGetMode() != KernelMode)
/* Perform vectored exception handling (a dummy in kernel mode) */
if (RtlCallVectoredExceptionHandlers(ExceptionRecord, Context))
{
/* Call any registered vectored handlers */
if (RtlCallVectoredExceptionHandlers(ExceptionRecord, Context))
{
/* Exception handled, continue execution */
return TRUE;
}
/* Exception handled, continue execution */
return TRUE;
}
/* Get the current stack limits and registration frame */

View file

@ -202,6 +202,27 @@ RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
return STATUS_SUCCESS;
}
struct _HEAP;
VOID
NTAPI
RtlpAddHeapToProcessList(struct _HEAP *Heap)
{
UNREFERENCED_PARAMETER(Heap);
}
VOID
NTAPI
RtlpRemoveHeapFromProcessList(struct _HEAP *Heap)
{
UNREFERENCED_PARAMETER(Heap);
}
VOID
RtlInitializeHeapManager(VOID)
{
}
#if DBG
VOID FASTCALL
CHECK_PAGED_CODE_RTL(char *file, int line)
@ -696,5 +717,14 @@ RtlpSafeCopyMemory(
return STATUS_SUCCESS;
}
BOOLEAN
NTAPI
RtlCallVectoredExceptionHandlers(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PCONTEXT Context)
{
/* In the kernel we don't have vectored exception handlers */
return FALSE;
}
/* EOF */