diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index fae20993228..f9600cb0f87 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -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 diff --git a/reactos/lib/rtl/CMakeLists.txt b/reactos/lib/rtl/CMakeLists.txt index 46b17c26309..57a2312d9b5 100644 --- a/reactos/lib/rtl/CMakeLists.txt +++ b/reactos/lib/rtl/CMakeLists.txt @@ -30,6 +30,7 @@ list(APPEND SOURCE heap.c heapdbg.c heappage.c + heapuser.c image.c interlck.c message.c diff --git a/reactos/lib/rtl/heap.c b/reactos/lib/rtl/heap.c index 6d0161c7d3f..c41b60dd77a 100644 --- a/reactos/lib/rtl/heap.c +++ b/reactos/lib/rtl/heap.c @@ -23,8 +23,6 @@ #define NDEBUG #include -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 */ diff --git a/reactos/lib/rtl/heap.h b/reactos/lib/rtl/heap.h index e76b742e3db..5a54c3f2a1d 100644 --- a/reactos/lib/rtl/heap.h +++ b/reactos/lib/rtl/heap.h @@ -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 diff --git a/reactos/lib/rtl/heappage.c b/reactos/lib/rtl/heappage.c index 8698180eda9..cd16910f138 100644 --- a/reactos/lib/rtl/heappage.c +++ b/reactos/lib/rtl/heappage.c @@ -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; diff --git a/reactos/lib/rtl/heapuser.c b/reactos/lib/rtl/heapuser.c new file mode 100644 index 00000000000..242307589ad --- /dev/null +++ b/reactos/lib/rtl/heapuser.c @@ -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 +#include + +#define NDEBUG +#include + +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); +} + diff --git a/reactos/lib/rtl/i386/except.c b/reactos/lib/rtl/i386/except.c index 0165fffc902..bef11af0851 100644 --- a/reactos/lib/rtl/i386/except.c +++ b/reactos/lib/rtl/i386/except.c @@ -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 */ diff --git a/reactos/ntoskrnl/rtl/libsupp.c b/reactos/ntoskrnl/rtl/libsupp.c index f9e4d603706..1afd455fab6 100644 --- a/reactos/ntoskrnl/rtl/libsupp.c +++ b/reactos/ntoskrnl/rtl/libsupp.c @@ -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 */