[NTOSKRNL]

- Keep APC delivery disabled while holding a Heap Lock, not just while acquiring/releasing it (Dedicated to Timo and Ged).
- Store the Heap Lock in non-paged pool, the only place where executive resources belong (Dedicated to patient people).
[RTL]
- Restructure/simplify/correct Heap and Heap Segment initialization (partially to cope with the changed Heap Lock interface).
- Restrict the location of Heap Segment headers to the base address of the Heap Segment (which frees up a whopping 60 bytes per Heap!).
- Cater for acquiring the Heap Lock exclusively or shared (the latter is only available in kernel-mode); only exclusive locking is used for now.
- Use a plain critical section to guard the Process Heap list, no reason to disguise it as a Heap Lock (saves us a handful more bytes).


svn path=/trunk/; revision=53761
This commit is contained in:
Roel Messiant 2011-09-19 16:52:37 +00:00
parent cf0a380afd
commit 2e6e9dd622
6 changed files with 214 additions and 227 deletions

View file

@ -112,32 +112,30 @@ RtlGetNtGlobalFlags(VOID)
NTSTATUS
NTAPI
RtlDeleteHeapLock(
PHEAP_LOCK Lock)
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
{
return RtlDeleteCriticalSection(&Lock->CriticalSection);
}
NTSTATUS
NTAPI
RtlEnterHeapLock(
PHEAP_LOCK Lock)
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
{
UNREFERENCED_PARAMETER(Exclusive);
return RtlEnterCriticalSection(&Lock->CriticalSection);
}
NTSTATUS
NTAPI
RtlInitializeHeapLock(
PHEAP_LOCK Lock)
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
{
return RtlInitializeCriticalSection(&Lock->CriticalSection);
return RtlInitializeCriticalSection(&(*Lock)->CriticalSection);
}
NTSTATUS
NTAPI
RtlLeaveHeapLock(
PHEAP_LOCK Lock)
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
{
return RtlLeaveCriticalSection(&Lock->CriticalSection);
}

View file

@ -23,7 +23,7 @@
#define NDEBUG
#include <debug.h>
HEAP_LOCK RtlpProcessHeapsListLock;
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
/* Bitmaps stuff */
@ -82,44 +82,58 @@ UCHAR FillPattern[HEAP_ENTRY_SIZE] =
/* FUNCTIONS *****************************************************************/
VOID NTAPI
RtlpInitializeHeap(PHEAP Heap,
PULONG HeaderSize,
ULONG Flags,
BOOLEAN AllocateLock,
PVOID Lock)
NTSTATUS NTAPI
RtlpInitializeHeap(OUT PHEAP Heap,
IN ULONG Flags,
IN PHEAP_LOCK Lock OPTIONAL,
IN PRTL_HEAP_PARAMETERS Parameters)
{
PVOID NextHeapBase = Heap + 1;
PHEAP_UCR_DESCRIPTOR UcrDescriptor;
ULONG NumUCRs = 8;
ULONG i;
ULONG Index;
SIZE_T HeaderSize;
NTSTATUS Status;
PHEAP_UCR_DESCRIPTOR UcrDescriptor;
/* Add UCRs size */
*HeaderSize += NumUCRs * sizeof(*UcrDescriptor);
/* Preconditions */
ASSERT(Heap != NULL);
ASSERT(Parameters != NULL);
ASSERT(!(Flags & HEAP_LOCK_USER_ALLOCATED));
ASSERT(!(Flags & HEAP_NO_SERIALIZE) || (Lock == NULL)); /* HEAP_NO_SERIALIZE => no lock */
/* Prepare a list of UCRs */
InitializeListHead(&Heap->UCRList);
InitializeListHead(&Heap->UCRSegments);
UcrDescriptor = NextHeapBase;
/* Start out with the size of a plain Heap header */
HeaderSize = ROUND_UP(sizeof(HEAP), sizeof(HEAP_ENTRY));
for (i=0; i<NumUCRs; i++, UcrDescriptor++)
/* Check if space needs to be added for the Heap Lock */
if (!(Flags & HEAP_NO_SERIALIZE))
{
InsertTailList(&Heap->UCRList, &UcrDescriptor->ListEntry);
if (Lock != NULL)
/* The user manages the Heap Lock */
Flags |= HEAP_LOCK_USER_ALLOCATED;
else
if (RtlpGetMode() == UserMode)
{
/* In user mode, the Heap Lock trails the Heap header */
Lock = (PHEAP_LOCK) ((ULONG_PTR) (Heap) + HeaderSize);
HeaderSize += ROUND_UP(sizeof(HEAP_LOCK), sizeof(HEAP_ENTRY));
}
}
NextHeapBase = UcrDescriptor;
// TODO: Add tagging
/* Add space for the initial Heap UnCommitted Range Descriptor list */
UcrDescriptor = (PHEAP_UCR_DESCRIPTOR) ((ULONG_PTR) (Heap) + HeaderSize);
HeaderSize += ROUND_UP(NumUCRs * sizeof(HEAP_UCR_DESCRIPTOR), sizeof(HEAP_ENTRY));
/* Round up header size again */
*HeaderSize = ROUND_UP(*HeaderSize, HEAP_ENTRY_SIZE);
/* Sanity check */
ASSERT(HeaderSize <= PAGE_SIZE);
ASSERT(*HeaderSize <= PAGE_SIZE);
/* Initialize heap's header */
Heap->Entry.Size = (USHORT)((*HeaderSize) >> HEAP_ENTRY_SHIFT);
/* Initialise the Heap Entry header containing the Heap header */
Heap->Entry.Size = HeaderSize >> HEAP_ENTRY_SHIFT;
Heap->Entry.Flags = HEAP_ENTRY_BUSY;
Heap->Entry.SmallTagIndex = LOBYTE(Heap->Entry.Size) ^ HIBYTE(Heap->Entry.Size) ^ Heap->Entry.Flags;
Heap->Entry.PreviousSize = 0;
Heap->Entry.SegmentOffset = 0;
Heap->Entry.UnusedBytes = 0;
/* Initialise the Heap header */
Heap->Signature = HEAP_SIGNATURE;
Heap->Flags = Flags;
Heap->ForceFlags = (Flags & (HEAP_NO_SERIALIZE |
@ -131,32 +145,64 @@ RtlpInitializeHeap(PHEAP Heap,
HEAP_TAIL_CHECKING_ENABLED |
HEAP_CREATE_ALIGN_16 |
HEAP_FREE_CHECKING_ENABLED));
Heap->HeaderValidateCopy = NULL;
Heap->HeaderValidateLength = ((PCHAR)NextHeapBase - (PCHAR)Heap);
/* Initialize free lists */
for (i=0; i<HEAP_FREELISTS; i++)
/* Initialise the Heap parameters */
Heap->VirtualMemoryThreshold = ROUND_UP(Parameters->VirtualMemoryThreshold, sizeof(HEAP_ENTRY)) >> HEAP_ENTRY_SHIFT;
Heap->SegmentReserve = Parameters->SegmentReserve;
Heap->SegmentCommit = Parameters->SegmentCommit;
Heap->DeCommitFreeBlockThreshold = Parameters->DeCommitFreeBlockThreshold >> HEAP_ENTRY_SHIFT;
Heap->DeCommitTotalFreeThreshold = Parameters->DeCommitTotalFreeThreshold >> HEAP_ENTRY_SHIFT;
Heap->MaximumAllocationSize = Parameters->MaximumAllocationSize;
Heap->CommitRoutine = Parameters->CommitRoutine;
/* Initialise the Heap validation info */
Heap->HeaderValidateCopy = NULL;
Heap->HeaderValidateLength = HeaderSize;
/* Initialise the Heap Lock */
if (!(Flags & HEAP_NO_SERIALIZE) && !(Flags & HEAP_LOCK_USER_ALLOCATED))
{
InitializeListHead(&Heap->FreeLists[i]);
Status = RtlInitializeHeapLock(&Lock);
if (!NT_SUCCESS(Status))
return Status;
}
Heap->LockVariable = Lock;
/* Initialise the Heap alignment info */
if (Flags & HEAP_CREATE_ALIGN_16)
{
Heap->AlignMask = (ULONG) ~15;
Heap->AlignRound = 15 + sizeof(HEAP_ENTRY);
}
else
{
Heap->AlignMask = (ULONG) ~(sizeof(HEAP_ENTRY) - 1);
Heap->AlignRound = 2 * sizeof(HEAP_ENTRY) - 1;
}
/* Initialize "big" allocations list */
if (Flags & HEAP_TAIL_CHECKING_ENABLED)
Heap->AlignRound += sizeof(HEAP_ENTRY);
/* Initialise the Heap Segment list */
for (Index = 0; Index < HEAP_SEGMENTS; ++Index)
Heap->Segments[Index] = NULL;
/* Initialise the Heap Free Heap Entry lists */
for (Index = 0; Index < HEAP_FREELISTS; ++Index)
InitializeListHead(&Heap->FreeLists[Index]);
/* Initialise the Heap Virtual Allocated Blocks list */
InitializeListHead(&Heap->VirtualAllocdBlocks);
/* Initialize lock */
if (AllocateLock)
{
Lock = NextHeapBase;
Status = RtlInitializeHeapLock((PHEAP_LOCK)Lock);
if (!NT_SUCCESS(Status))
{
DPRINT1("Initializing the lock failed!\n");
return /*NULL*/; // FIXME!
}
}
/* Initialise the Heap UnCommitted Region lists */
InitializeListHead(&Heap->UCRSegments);
InitializeListHead(&Heap->UCRList);
/* Set the lock variable */
Heap->LockVariable = Lock;
/* Register the initial Heap UnCommitted Region Descriptors */
for (Index = 0; Index < NumUCRs; ++Index)
InsertTailList(&Heap->UCRList, &UcrDescriptor[Index].ListEntry);
return STATUS_SUCCESS;
}
VOID FORCEINLINE
@ -821,92 +867,76 @@ RtlpDeCommitFreeBlock(PHEAP Heap,
}
BOOLEAN NTAPI
RtlpInitializeHeapSegment(PHEAP Heap,
PHEAP_SEGMENT Segment,
UCHAR SegmentIndex,
ULONG Flags,
PVOID BaseAddress,
PVOID UncommittedBase,
PVOID LimitAddress)
RtlpInitializeHeapSegment(IN OUT PHEAP Heap,
OUT PHEAP_SEGMENT Segment,
IN UCHAR SegmentIndex,
IN ULONG SegmentFlags,
IN SIZE_T SegmentReserve,
IN SIZE_T SegmentCommit)
{
ULONG Pages, CommitSize;
PHEAP_ENTRY HeapEntry;
USHORT PreviousSize = 0, NewSize;
NTSTATUS Status;
Pages = ((PCHAR)LimitAddress - (PCHAR)BaseAddress) / PAGE_SIZE;
/* Preconditions */
ASSERT(Heap != NULL);
ASSERT(Segment != NULL);
ASSERT(SegmentCommit >= PAGE_SIZE);
ASSERT(ROUND_DOWN(SegmentCommit, PAGE_SIZE) == SegmentCommit);
ASSERT(SegmentReserve >= SegmentCommit);
ASSERT(ROUND_DOWN(SegmentReserve, PAGE_SIZE) == SegmentReserve);
HeapEntry = (PHEAP_ENTRY)ROUND_UP(Segment + 1, HEAP_ENTRY_SIZE);
DPRINT("RtlpInitializeHeapSegment(%p %p %x %x %lx %lx)\n", Heap, Segment, SegmentIndex, SegmentFlags, SegmentReserve, SegmentCommit);
DPRINT("RtlpInitializeHeapSegment(%p %p %x %x %p %p %p)\n", Heap, Segment, SegmentIndex, Flags, BaseAddress, UncommittedBase, LimitAddress);
DPRINT("Pages %x, HeapEntry %p, sizeof(HEAP_SEGMENT) %x\n", Pages, HeapEntry, sizeof(HEAP_SEGMENT));
/* Check if it's the first segment and remember its size */
if (Heap == BaseAddress)
PreviousSize = Heap->Entry.Size;
NewSize = ((PCHAR)HeapEntry - (PCHAR)Segment) >> HEAP_ENTRY_SHIFT;
if ((PVOID)(HeapEntry + 1) >= UncommittedBase)
/* Initialise the Heap Entry header if this is not the first Heap Segment */
if ((PHEAP_SEGMENT) (Heap) != Segment)
{
/* Check if it goes beyond the limit */
if ((PVOID)(HeapEntry + 1) >= LimitAddress)
return FALSE;
/* Need to commit memory */
CommitSize = (PCHAR)(HeapEntry + 1) - (PCHAR)UncommittedBase;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
(PVOID)&UncommittedBase,
0,
&CommitSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Committing page failed with status 0x%08X\n", Status);
return FALSE;
}
DPRINT("Committed %d bytes at base %p\n", CommitSize, UncommittedBase);
/* Calcule the new uncommitted base */
UncommittedBase = (PVOID)((PCHAR)UncommittedBase + CommitSize);
Segment->Entry.Size = ROUND_UP(sizeof(HEAP_SEGMENT), sizeof(HEAP_ENTRY)) >> HEAP_ENTRY_SHIFT;
Segment->Entry.Flags = HEAP_ENTRY_BUSY;
Segment->Entry.SmallTagIndex = LOBYTE(Segment->Entry.Size) ^ HIBYTE(Segment->Entry.Size) ^ Segment->Entry.Flags;
Segment->Entry.PreviousSize = 0;
Segment->Entry.SegmentOffset = SegmentIndex;
Segment->Entry.UnusedBytes = 0;
}
/* Initialize the segment entry */
Segment->Entry.PreviousSize = PreviousSize;
Segment->Entry.Size = NewSize;
Segment->Entry.Flags = HEAP_ENTRY_BUSY;
Segment->Entry.SegmentOffset = SegmentIndex;
/* Sanity check */
ASSERT((Segment->Entry.Size << HEAP_ENTRY_SHIFT) <= PAGE_SIZE);
/* Initialize the segment itself */
/* Initialise the Heap Segment header */
Segment->SegmentSignature = HEAP_SEGMENT_SIGNATURE;
Segment->SegmentFlags = SegmentFlags;
Segment->Heap = Heap;
Segment->BaseAddress = BaseAddress;
Segment->FirstEntry = HeapEntry;
Segment->LastValidEntry = (PHEAP_ENTRY)((PCHAR)BaseAddress + Pages * PAGE_SIZE);
Segment->NumberOfPages = Pages;
Segment->NumberOfUnCommittedPages = ((PCHAR)LimitAddress - (PCHAR)UncommittedBase) / PAGE_SIZE;
InitializeListHead(&Segment->UCRSegmentList);
/* Insert uncommitted pages into UCR (uncommitted ranges) list */
if (Segment->NumberOfUnCommittedPages)
{
RtlpInsertUnCommittedPages(Segment, (ULONG_PTR)UncommittedBase, Segment->NumberOfUnCommittedPages * PAGE_SIZE);
}
/* Set the segment index pointer */
Heap->Segments[SegmentIndex] = Segment;
/* Prepare a free heap entry */
HeapEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
HeapEntry->PreviousSize = Segment->Entry.Size;
HeapEntry->SegmentOffset = SegmentIndex;
/* Initialise the Heap Segment location information */
Segment->BaseAddress = Segment;
Segment->NumberOfPages = SegmentReserve >> PAGE_SHIFT;
/* Insert it */
RtlpInsertFreeBlock(Heap, (PHEAP_FREE_ENTRY)HeapEntry, (PHEAP_ENTRY)UncommittedBase - HeapEntry);
/* Initialise the Heap Entries contained within the Heap Segment */
Segment->FirstEntry = &Segment->Entry + Segment->Entry.Size;
Segment->LastValidEntry = (PHEAP_ENTRY) ((ULONG_PTR) (Segment) + SegmentReserve);
return TRUE;
if ((Segment->Entry.Size << HEAP_ENTRY_SHIFT) < SegmentCommit)
{
HeapEntry = Segment->FirstEntry;
/* Prepare a Free Heap Entry header */
HeapEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
HeapEntry->PreviousSize = Segment->Entry.Size;
HeapEntry->SegmentOffset = SegmentIndex;
/* Register the Free Heap Entry */
RtlpInsertFreeBlock(Heap, (PHEAP_FREE_ENTRY) HeapEntry, (SegmentCommit >> HEAP_ENTRY_SHIFT) - Segment->Entry.Size);
}
/* Initialise the Heap Segment UnCommitted Range information */
Segment->NumberOfUnCommittedPages = (SegmentReserve - SegmentCommit) >> PAGE_SHIFT;
Segment->NumberOfUnCommittedRanges = 0;
InitializeListHead(&Segment->UCRSegmentList);
/* Register the UnCommitted Range of the Heap Segment */
if (Segment->NumberOfUnCommittedPages != 0)
RtlpInsertUnCommittedPages(Segment, (ULONG_PTR) (Segment) + SegmentCommit, SegmentReserve - SegmentCommit);
return STATUS_SUCCESS;
}
VOID NTAPI
@ -944,7 +974,7 @@ RtlpAddHeapToProcessList(PHEAP Heap)
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterHeapLock(&RtlpProcessHeapsListLock);
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
//_SEH2_TRY {
/* Check if max number of heaps reached */
@ -961,7 +991,7 @@ RtlpAddHeapToProcessList(PHEAP Heap)
// } _SEH2_FINALLY {
/* Release the lock */
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
// } _SEH2_END
}
@ -978,7 +1008,7 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterHeapLock(&RtlpProcessHeapsListLock);
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
/* Check if we don't need anything to do */
if ((Heap->ProcessHeapsListIndex == 0) ||
@ -986,7 +1016,7 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
(Peb->NumberOfHeaps == 0))
{
/* Release the lock */
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
return;
}
@ -1023,7 +1053,7 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
Heap->ProcessHeapsListIndex = 0;
/* Release the lock */
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
}
PHEAP_FREE_ENTRY NTAPI
@ -1228,13 +1258,7 @@ RtlpExtendHeap(PHEAP Heap,
/* Initialize heap segment if commit was successful */
if (NT_SUCCESS(Status))
{
if (!RtlpInitializeHeapSegment(Heap, Segment, EmptyIndex, 0, Segment,
(PCHAR)Segment + CommitSize, (PCHAR)Segment + ReserveSize))
{
Status = STATUS_NO_MEMORY;
}
}
Status = RtlpInitializeHeapSegment(Heap, Segment, EmptyIndex, 0, ReserveSize, CommitSize);
/* If everything worked - cool */
if (NT_SUCCESS(Status)) return (PHEAP_FREE_ENTRY)Segment->FirstEntry;
@ -1298,8 +1322,7 @@ RtlCreateHeap(ULONG Flags,
ULONG NtGlobalFlags = RtlGetNtGlobalFlags();
ULONG HeapSegmentFlags = 0;
NTSTATUS Status;
ULONG MaxBlockSize, HeaderSize;
BOOLEAN AllocateLock = FALSE;
ULONG MaxBlockSize;
/* Check for a special heap */
if (RtlpPageHeapEnabled && !Addr && !Lock)
@ -1422,25 +1445,9 @@ RtlCreateHeap(ULONG Flags,
if (RtlpHeapIsSpecial(Flags))
return RtlDebugCreateHeap(Flags, Addr, TotalSize, CommitSize, Lock, Parameters);
/* Calculate header size */
HeaderSize = sizeof(HEAP);
if (!(Flags & HEAP_NO_SERIALIZE))
{
if (Lock)
{
Flags |= HEAP_LOCK_USER_ALLOCATED;
}
else
{
HeaderSize += sizeof(HEAP_LOCK);
AllocateLock = TRUE;
}
}
else if (Lock)
{
/* Invalid parameters */
/* Without serialization, a lock makes no sense */
if ((Flags & HEAP_NO_SERIALIZE) && (Lock != NULL))
return NULL;
}
/* See if we are already provided with an address for the heap */
if (Addr)
@ -1583,48 +1590,23 @@ RtlCreateHeap(ULONG Flags,
UncommittedAddress = (PCHAR)UncommittedAddress + CommitSize;
}
DPRINT("Created heap %p, CommitSize %x, ReserveSize %x\n", Heap, CommitSize, TotalSize);
/* Initialize the heap */
RtlpInitializeHeap(Heap, &HeaderSize, Flags, AllocateLock, Lock);
/* Initialize heap's first segment */
if (!RtlpInitializeHeapSegment(Heap,
(PHEAP_SEGMENT)((PCHAR)Heap + HeaderSize),
0,
HeapSegmentFlags,
CommittedAddress,
UncommittedAddress,
(PCHAR)CommittedAddress + TotalSize))
Status = RtlpInitializeHeap(Heap, Flags, Lock, Parameters);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize heap segment\n");
DPRINT1("Failed to initialize heap (%x)\n", Status);
return NULL;
}
/* Set other data */
Heap->ProcessHeapsListIndex = 0;
Heap->SegmentCommit = Parameters->SegmentCommit;
Heap->SegmentReserve = Parameters->SegmentReserve;
Heap->DeCommitFreeBlockThreshold = Parameters->DeCommitFreeBlockThreshold >> HEAP_ENTRY_SHIFT;
Heap->DeCommitTotalFreeThreshold = Parameters->DeCommitTotalFreeThreshold >> HEAP_ENTRY_SHIFT;
Heap->MaximumAllocationSize = Parameters->MaximumAllocationSize;
Heap->VirtualMemoryThreshold = ROUND_UP(Parameters->VirtualMemoryThreshold, HEAP_ENTRY_SIZE) >> HEAP_ENTRY_SHIFT;
Heap->CommitRoutine = Parameters->CommitRoutine;
/* Set alignment */
if (Flags & HEAP_CREATE_ALIGN_16)
/* Initialize heap's first segment */
Status = RtlpInitializeHeapSegment(Heap, (PHEAP_SEGMENT) (Heap), 0, HeapSegmentFlags, TotalSize, CommitSize);
if (!NT_SUCCESS(Status))
{
Heap->AlignMask = (ULONG)~15;
Heap->AlignRound = 15 + sizeof(HEAP_ENTRY);
}
else
{
Heap->AlignMask = (ULONG)~(HEAP_ENTRY_SIZE - 1);
Heap->AlignRound = HEAP_ENTRY_SIZE - 1 + sizeof(HEAP_ENTRY);
DPRINT1("Failed to initialize heap segment (%x)\n", Status);
return NULL;
}
if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
Heap->AlignRound += HEAP_ENTRY_SIZE;
DPRINT("Created heap %p, CommitSize %x, ReserveSize %x\n", Heap, CommitSize, TotalSize);
/* Add heap to process list in case of usermode heap */
if (RtlpGetMode() == UserMode)
@ -1634,7 +1616,6 @@ RtlCreateHeap(ULONG Flags,
// FIXME: What about lookasides?
}
DPRINT("Heap %p, flags 0x%08x\n", Heap, Heap->Flags);
return Heap;
}
@ -2063,7 +2044,7 @@ RtlAllocateHeap(IN PVOID HeapPtr,
/* Acquire the lock if necessary */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
}
@ -2265,7 +2246,7 @@ BOOLEAN NTAPI RtlFreeHeap(
/* Lock if necessary */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
Locked = TRUE;
}
@ -2690,7 +2671,7 @@ RtlReAllocateHeap(HANDLE HeapPtr,
/* Acquire the lock if necessary */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
Flags &= ~HEAP_NO_SERIALIZE;
}
@ -3071,7 +3052,7 @@ RtlLockHeap(IN HANDLE HeapPtr)
/* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
}
return TRUE;
@ -3651,7 +3632,7 @@ BOOLEAN NTAPI RtlValidateHeap(
/* Acquire the lock if necessary */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
}
@ -3682,7 +3663,7 @@ RtlInitializeHeapManager(VOID)
Peb->NumberOfHeaps = 0;
/* Initialize the process heaps list protecting lock */
RtlInitializeHeapLock(&RtlpProcessHeapsListLock);
RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
}
@ -3759,7 +3740,7 @@ RtlSetUserValueHeap(IN PVOID HeapHandle,
/* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
}
@ -3818,7 +3799,7 @@ RtlSetUserFlagsHeap(IN PVOID HeapHandle,
/* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
}
@ -3874,7 +3855,7 @@ RtlGetUserInfoHeap(IN PVOID HeapHandle,
/* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
}

View file

@ -320,7 +320,7 @@ typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
} HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
/* Global variables */
extern HEAP_LOCK RtlpProcessHeapsListLock;
extern RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
extern BOOLEAN RtlpPageHeapEnabled;
/* Functions declarations */

View file

@ -163,7 +163,7 @@ RtlDebugAllocateHeap(PVOID HeapPtr,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
@ -230,7 +230,7 @@ RtlDebugReAllocateHeap(HANDLE HeapPtr,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
@ -288,7 +288,7 @@ RtlDebugFreeHeap(HANDLE HeapPtr,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
@ -345,7 +345,7 @@ RtlDebugGetUserInfoHeap(PVOID HeapHandle,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
@ -397,7 +397,7 @@ RtlDebugSetUserValueHeap(PVOID HeapHandle,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
@ -461,7 +461,7 @@ RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
@ -516,7 +516,7 @@ RtlDebugSizeHeap(HANDLE HeapPtr,
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
RtlEnterHeapLock(Heap->LockVariable, TRUE);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */

View file

@ -86,19 +86,19 @@ RtlpCaptureStackLimits(
NTSTATUS
NTAPI
RtlDeleteHeapLock(PHEAP_LOCK Lock);
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock);
NTSTATUS
NTAPI
RtlEnterHeapLock(PHEAP_LOCK Lock);
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive);
NTSTATUS
NTAPI
RtlInitializeHeapLock(PHEAP_LOCK Lock);
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock);
NTSTATUS
NTAPI
RtlLeaveHeapLock(PHEAP_LOCK Lock);
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock);
BOOLEAN
NTAPI

View file

@ -156,41 +156,49 @@ RtlGetCurrentPeb(VOID)
NTSTATUS
NTAPI
RtlDeleteHeapLock(
PHEAP_LOCK Lock)
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
{
ExDeleteResource(&Lock->Resource);
ExDeleteResourceLite(&Lock->Resource);
ExFreePool(Lock);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RtlEnterHeapLock(
PHEAP_LOCK Lock)
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
{
KeEnterCriticalRegion();
ExAcquireResourceExclusive(&Lock->Resource, TRUE);
KeLeaveCriticalRegion();
if (Exclusive)
ExAcquireResourceExclusiveLite(&Lock->Resource, TRUE);
else
ExAcquireResourceSharedLite(&Lock->Resource, TRUE);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RtlInitializeHeapLock(
PHEAP_LOCK Lock)
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
{
ExInitializeResource(&Lock->Resource);
PHEAP_LOCK HeapLock = ExAllocatePool(NonPagedPool, sizeof(HEAP_LOCK));
if (HeapLock == NULL)
return STATUS_NO_MEMORY;
ExInitializeResourceLite(&HeapLock->Resource);
*Lock = HeapLock;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RtlLeaveHeapLock(
PHEAP_LOCK Lock)
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
{
KeEnterCriticalRegion();
ExReleaseResource(&Lock->Resource);
ExReleaseResourceLite(&Lock->Resource);
KeLeaveCriticalRegion();
return STATUS_SUCCESS;
}