[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 RtlpInitializeVectoredExceptionHandling(VOID);
VOID NTAPI RtlpInitDeferedCriticalSection(VOID); VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
VOID RtlInitializeHeapManager(VOID); VOID NTAPI RtlInitializeHeapManager(VOID);
extern BOOLEAN RtlpPageHeapEnabled; extern BOOLEAN RtlpPageHeapEnabled;
ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c

View file

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

View file

@ -23,8 +23,6 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
/* Bitmaps stuff */ /* Bitmaps stuff */
/* How many least significant bits are clear */ /* 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 PHEAP_FREE_ENTRY NTAPI
RtlpCoalesceHeap(PHEAP Heap) RtlpCoalesceHeap(PHEAP Heap)
{ {
@ -3685,22 +3591,6 @@ BOOLEAN NTAPI RtlValidateHeap(
return HeapValid; 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 * @implemented
*/ */

View file

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

View file

@ -61,7 +61,7 @@ typedef struct _DPH_HEAP_ROOT
{ {
ULONG Signature; ULONG Signature;
ULONG HeapFlags; ULONG HeapFlags;
PRTL_CRITICAL_SECTION HeapCritSect; PHEAP_LOCK HeapCritSect;
ULONG nRemoteLockAcquired; ULONG nRemoteLockAcquired;
PDPH_HEAP_BLOCK pVirtualStorageListHead; PDPH_HEAP_BLOCK pVirtualStorageListHead;
@ -110,11 +110,11 @@ WCHAR RtlpDphTargetDlls[512];
LIST_ENTRY RtlpDphPageHeapList; LIST_ENTRY RtlpDphPageHeapList;
BOOLEAN RtlpDphPageHeapListInitialized; BOOLEAN RtlpDphPageHeapListInitialized;
RTL_CRITICAL_SECTION RtlpDphPageHeapListLock; PHEAP_LOCK RtlpDphPageHeapListLock;
ULONG RtlpDphPageHeapListLength; ULONG RtlpDphPageHeapListLength;
UNICODE_STRING RtlpDphTargetDllsUnicode; UNICODE_STRING RtlpDphTargetDllsUnicode;
RTL_CRITICAL_SECTION RtlpDphDelayedFreeQueueLock; PHEAP_LOCK RtlpDphDelayedFreeQueueLock;
LIST_ENTRY RtlpDphDelayedFreeQueue; LIST_ENTRY RtlpDphDelayedFreeQueue;
SLIST_HEADER RtlpDphDelayedTemporaryPushList; SLIST_HEADER RtlpDphDelayedTemporaryPushList;
SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks; SIZE_T RtlpDphMemoryUsedByDelayedFreeBlocks;
@ -234,7 +234,7 @@ RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
if (Flags & HEAP_NO_SERIALIZE) if (Flags & HEAP_NO_SERIALIZE)
{ {
/* More complex scenario */ /* More complex scenario */
if (!RtlTryEnterCriticalSection(DphRoot->HeapCritSect)) if (!RtlEnterHeapLock(DphRoot->HeapCritSect, TRUE))
{ {
if (!DphRoot->nRemoteLockAcquired) if (!DphRoot->nRemoteLockAcquired)
{ {
@ -246,13 +246,13 @@ RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
} }
/* Enter the heap's critical section */ /* Enter the heap's critical section */
RtlEnterCriticalSection(DphRoot->HeapCritSect); RtlEnterHeapLock(DphRoot->HeapCritSect, TRUE);
} }
} }
else else
{ {
/* Just enter the heap's critical section */ /* 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) RtlpDphLeaveCriticalSection(PDPH_HEAP_ROOT DphRoot)
{ {
/* Just leave the heap's critical section */ /* Just leave the heap's critical section */
RtlLeaveCriticalSection(DphRoot->HeapCritSect); RtlLeaveHeapLock(DphRoot->HeapCritSect);
} }
@ -1161,7 +1161,7 @@ RtlpDphInitializeDelayedFreeQueue()
{ {
NTSTATUS Status; NTSTATUS Status;
Status = RtlInitializeCriticalSection(&RtlpDphDelayedFreeQueueLock); Status = RtlInitializeHeapLock(&RtlpDphDelayedFreeQueueLock);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// TODO: Log this error! // 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 */ then it releases the lock and frees the blocks. But let's make it simple for now */
/* Acquire the delayed free queue lock */ /* Acquire the delayed free queue lock */
RtlEnterCriticalSection(&RtlpDphDelayedFreeQueueLock); RtlEnterHeapLock(RtlpDphDelayedFreeQueueLock, TRUE);
/* Traverse the list */ /* Traverse the list */
Current = RtlpDphDelayedFreeQueue.Flink; Current = RtlpDphDelayedFreeQueue.Flink;
@ -1230,7 +1230,7 @@ RtlpDphFreeDelayedBlocksFromHeap(PDPH_HEAP_ROOT DphRoot,
} }
/* Release the delayed free queue lock */ /* Release the delayed free queue lock */
RtlLeaveCriticalSection(&RtlpDphDelayedFreeQueueLock); RtlLeaveHeapLock(RtlpDphDelayedFreeQueueLock);
} }
NTSTATUS NTAPI NTSTATUS NTAPI
@ -1391,7 +1391,7 @@ RtlpDphProcessStartupInitialization()
/* Initialize the DPH heap list and its critical section */ /* Initialize the DPH heap list and its critical section */
InitializeListHead(&RtlpDphPageHeapList); InitializeListHead(&RtlpDphPageHeapList);
Status = RtlInitializeCriticalSection(&RtlpDphPageHeapListLock); Status = RtlInitializeHeapLock(&RtlpDphPageHeapListLock);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ASSERT(FALSE); ASSERT(FALSE);
@ -1485,13 +1485,12 @@ RtlpPageHeapCreate(ULONG Flags,
/* Initialize the DPH root */ /* Initialize the DPH root */
DphRoot->Signature = DPH_SIGNATURE; DphRoot->Signature = DPH_SIGNATURE;
DphRoot->HeapFlags = Flags; DphRoot->HeapFlags = Flags;
DphRoot->HeapCritSect = (PRTL_CRITICAL_SECTION)((PCHAR)DphRoot + DPH_POOL_SIZE);
DphRoot->ExtraFlags = RtlpDphGlobalFlags; DphRoot->ExtraFlags = RtlpDphGlobalFlags;
ZwQueryPerformanceCounter(&PerfCounter, NULL); ZwQueryPerformanceCounter(&PerfCounter, NULL);
DphRoot->Seed = PerfCounter.LowPart; DphRoot->Seed = PerfCounter.LowPart;
RtlInitializeCriticalSection(DphRoot->HeapCritSect); RtlInitializeHeapLock(&DphRoot->HeapCritSect);
InitializeListHead(&DphRoot->AvailableAllocationHead); InitializeListHead(&DphRoot->AvailableAllocationHead);
/* Create a normal heap for this paged heap */ /* Create a normal heap for this paged heap */
@ -1539,7 +1538,7 @@ RtlpPageHeapCreate(ULONG Flags,
if (!RtlpDphPageHeapListInitialized) RtlpDphProcessStartupInitialization(); if (!RtlpDphPageHeapListInitialized) RtlpDphProcessStartupInitialization();
/* Acquire the heap list lock */ /* Acquire the heap list lock */
RtlEnterCriticalSection(&RtlpDphPageHeapListLock); RtlEnterHeapLock(RtlpDphPageHeapListLock, TRUE);
/* Insert this heap to the tail of the global list */ /* Insert this heap to the tail of the global list */
InsertTailList(&RtlpDphPageHeapList, &DphRoot->NextHeap); InsertTailList(&RtlpDphPageHeapList, &DphRoot->NextHeap);
@ -1548,7 +1547,7 @@ RtlpPageHeapCreate(ULONG Flags,
RtlpDphPageHeapListLength++; RtlpDphPageHeapListLength++;
/* Release the heap list lock */ /* Release the heap list lock */
RtlLeaveCriticalSection(&RtlpDphPageHeapListLock); RtlLeaveHeapLock(RtlpDphPageHeapListLock);
if (RtlpDphDebugOptions & DPH_DEBUG_VERBOSE) if (RtlpDphDebugOptions & DPH_DEBUG_VERBOSE)
{ {
@ -1611,18 +1610,18 @@ RtlpPageHeapDestroy(HANDLE HeapPtr)
} }
/* Acquire the global heap list lock */ /* Acquire the global heap list lock */
RtlEnterCriticalSection(&RtlpDphPageHeapListLock); RtlEnterHeapLock(RtlpDphPageHeapListLock, TRUE);
/* Remove the entry and decrement the global counter */ /* Remove the entry and decrement the global counter */
RemoveEntryList(&DphRoot->NextHeap); RemoveEntryList(&DphRoot->NextHeap);
RtlpDphPageHeapListLength--; RtlpDphPageHeapListLength--;
/* Release the global heap list lock */ /* Release the global heap list lock */
RtlLeaveCriticalSection(&RtlpDphPageHeapListLock); RtlLeaveHeapLock(RtlpDphPageHeapListLock);
/* Leave and delete this heap's critical section */ /* Leave and delete this heap's critical section */
RtlLeaveCriticalSection(DphRoot->HeapCritSect); RtlLeaveHeapLock(DphRoot->HeapCritSect);
RtlDeleteCriticalSection(DphRoot->HeapCritSect); RtlDeleteHeapLock(DphRoot->HeapCritSect);
/* Now go through all virtual list nodes and release the VM */ /* Now go through all virtual list nodes and release the VM */
Node = DphRoot->pVirtualStorageListHead; 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,16 +74,12 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
ULONG_PTR StackLow, StackHigh; ULONG_PTR StackLow, StackHigh;
ULONG_PTR RegistrationFrameEnd; ULONG_PTR RegistrationFrameEnd;
/* Perform vectored exception handling if we are in user mode */ /* Perform vectored exception handling (a dummy in kernel mode) */
if (RtlpGetMode() != KernelMode)
{
/* Call any registered vectored handlers */
if (RtlCallVectoredExceptionHandlers(ExceptionRecord, Context)) if (RtlCallVectoredExceptionHandlers(ExceptionRecord, Context))
{ {
/* Exception handled, continue execution */ /* Exception handled, continue execution */
return TRUE; return TRUE;
} }
}
/* Get the current stack limits and registration frame */ /* Get the current stack limits and registration frame */
RtlpGetStackLimits(&StackLow, &StackHigh); RtlpGetStackLimits(&StackLow, &StackHigh);

View file

@ -202,6 +202,27 @@ RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
return STATUS_SUCCESS; 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 #if DBG
VOID FASTCALL VOID FASTCALL
CHECK_PAGED_CODE_RTL(char *file, int line) CHECK_PAGED_CODE_RTL(char *file, int line)
@ -696,5 +717,14 @@ RtlpSafeCopyMemory(
return STATUS_SUCCESS; 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 */ /* EOF */