mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
- Switch to using ARM3 paged pool -- all pool allocations are now handled by ARM3, which should be much more efficient, and combines both NP and P code together.
svn path=/trunk/; revision=44885
This commit is contained in:
parent
b69d9da41a
commit
3c027e728c
|
@ -594,7 +594,7 @@ QSI_DEF(SystemPerformanceInformation)
|
|||
Spi->Spare3Count = 0; /* FIXME */
|
||||
|
||||
Spi->ResidentSystemCachePage = MiMemoryConsumers[MC_CACHE].PagesUsed;
|
||||
Spi->ResidentPagedPoolPage = MmPagedPoolSize; /* FIXME */
|
||||
Spi->ResidentPagedPoolPage = MiMemoryConsumers[MC_PPOOL].PagesUsed; /* FIXME */
|
||||
|
||||
Spi->ResidentSystemDriverPage = 0; /* FIXME */
|
||||
Spi->CcFastReadNoWait = 0; /* FIXME */
|
||||
|
|
|
@ -178,11 +178,14 @@ ExUnlockPool(IN PPOOL_DESCRIPTOR Descriptor,
|
|||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType,
|
||||
IN SIZE_T NumberOfBytes,
|
||||
IN ULONG Tag)
|
||||
ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
|
||||
IN SIZE_T NumberOfBytes,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
PPOOL_DESCRIPTOR PoolDesc;
|
||||
PLIST_ENTRY ListHead;
|
||||
|
@ -449,10 +452,13 @@ ExAllocateArmPoolWithTag(IN POOL_TYPE PoolType,
|
|||
return ++Entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
ExAllocateArmPool(POOL_TYPE PoolType,
|
||||
SIZE_T NumberOfBytes)
|
||||
ExAllocatePool(POOL_TYPE PoolType,
|
||||
SIZE_T NumberOfBytes)
|
||||
{
|
||||
//
|
||||
// Use a default tag of "None"
|
||||
|
@ -460,10 +466,13 @@ ExAllocateArmPool(POOL_TYPE PoolType,
|
|||
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, 'enoN');
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
ExFreeArmPoolWithTag(IN PVOID P,
|
||||
IN ULONG TagToFree)
|
||||
ExFreePoolWithTag(IN PVOID P,
|
||||
IN ULONG TagToFree)
|
||||
{
|
||||
PPOOL_HEADER Entry, NextEntry;
|
||||
ULONG BlockSize;
|
||||
|
@ -633,14 +642,17 @@ ExFreeArmPoolWithTag(IN PVOID P,
|
|||
ExUnlockPool(PoolDesc, OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
ExFreeArmPool(PVOID P)
|
||||
ExFreePool(PVOID P)
|
||||
{
|
||||
//
|
||||
// Just free without checking for the tag
|
||||
//
|
||||
ExFreeArmPoolWithTag(P, 0);
|
||||
ExFreePoolWithTag(P, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/mm/dbgpool.c
|
||||
* PURPOSE: Debug version of a pool allocator
|
||||
* PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
typedef struct _EI_WHOLE_PAGE_HEADER {
|
||||
PVOID ActualAddress;
|
||||
ULONG Size;
|
||||
ULONG Tag;
|
||||
} EI_WHOLE_PAGE_HEADER, *PEI_WHOLE_PAGE_HEADER;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ExpIsPoolTagDebuggable(ULONG Tag)
|
||||
{
|
||||
#if 0
|
||||
if (Tag == 'llaC') return FALSE;
|
||||
if (Tag == 'virD') return FALSE;
|
||||
if (Tag == 'iveD') return FALSE;
|
||||
if (Tag == 'padA') return FALSE;
|
||||
|
||||
if (Tag == 'dSeS') return FALSE;
|
||||
if (Tag == 'iDbO') return FALSE;
|
||||
if (Tag == 'mNbO') return FALSE;
|
||||
if (Tag == 'DNbO') return FALSE;
|
||||
if (Tag == 'btbO') return FALSE;
|
||||
if (Tag == 'cSbO') return FALSE;
|
||||
//if (Tag == 'iSeS') return FALSE;
|
||||
//if (Tag == 'cAeS') return FALSE;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
ExpAllocateDebugPool(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Caller, BOOLEAN EndOfPage)
|
||||
{
|
||||
ULONG UserSize, TotalSize, AlignedSize;
|
||||
ULONG_PTR UserData, GuardArea;
|
||||
PEI_WHOLE_PAGE_HEADER Header;
|
||||
ULONG_PTR Buffer;
|
||||
|
||||
/* Calculate sizes */
|
||||
AlignedSize = ROUND_UP(Size, MM_POOL_ALIGNMENT);
|
||||
UserSize = AlignedSize + sizeof(EI_WHOLE_PAGE_HEADER);
|
||||
TotalSize = UserSize + 2*PAGE_SIZE;
|
||||
|
||||
/* Right now we support only end-of-page allocations */
|
||||
ASSERT(EndOfPage);
|
||||
|
||||
/* Allocate space using default routine */
|
||||
if (Type & PAGED_POOL_MASK)
|
||||
{
|
||||
Buffer = (ULONG_PTR)
|
||||
ExAllocatePagedPoolWithTag(Type, TotalSize, Tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* If allocation failed - fail too */
|
||||
if (!Buffer)
|
||||
{
|
||||
DPRINT1("A big problem! Pool allocation failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Calculate guard area as placed on a page boundary
|
||||
* at the end of allocated area */
|
||||
GuardArea = PAGE_ROUND_DOWN(Buffer + TotalSize - PAGE_SIZE + 1);
|
||||
|
||||
/* Calculate user data and header pointers */
|
||||
UserData = GuardArea - AlignedSize;
|
||||
Header = (PEI_WHOLE_PAGE_HEADER)(UserData - sizeof(EI_WHOLE_PAGE_HEADER));
|
||||
|
||||
/* Fill out the header */
|
||||
Header->ActualAddress = (PVOID)Buffer;
|
||||
Header->Tag = Tag;
|
||||
Header->Size = AlignedSize;
|
||||
|
||||
/* Protect the guard page */
|
||||
MmSetPageProtect(NULL, (PVOID)GuardArea, PAGE_NOACCESS);
|
||||
|
||||
DPRINT("Allocating whole page block Tag %c%c%c%c, Buffer %p, Header %p, UserData %p, GuardArea %p, Size %d\n",
|
||||
Tag & 0xFF, (Tag >> 8) & 0xFF,
|
||||
(Tag >> 16) & 0xFF, (Tag >> 24) & 0xFF,
|
||||
Buffer, Header, UserData, GuardArea, Size);
|
||||
|
||||
return (PVOID)UserData;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ExpFreeDebugPool(PVOID Block, BOOLEAN PagedPool)
|
||||
{
|
||||
PEI_WHOLE_PAGE_HEADER Header;
|
||||
PVOID ProtectedPage;
|
||||
|
||||
/* Get pointer to our special header */
|
||||
Header = (PEI_WHOLE_PAGE_HEADER)
|
||||
(((PCHAR)Block) - sizeof(EI_WHOLE_PAGE_HEADER));
|
||||
|
||||
DPRINT("Freeing whole page block at %08x (Tag %c%c%c%c, %x Header %x)\n", Block,
|
||||
Header->Tag & 0xFF, (Header->Tag >> 8) & 0xFF,
|
||||
(Header->Tag >> 16) & 0xFF, (Header->Tag >> 24) & 0xFF, Header->Tag, Header);
|
||||
|
||||
/* Calculate protected page adresss */
|
||||
ProtectedPage = ((PCHAR)Block) + Header->Size;
|
||||
|
||||
/* Unprotect it */
|
||||
MmSetPageProtect(NULL, ProtectedPage, PAGE_READWRITE);
|
||||
|
||||
/* Free storage */
|
||||
ASSERT(PagedPool);
|
||||
ExFreePagedPool(Header->ActualAddress);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -198,21 +198,6 @@ MiInitSystemMemoryAreas()
|
|||
BoundaryAddressMultiple);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
//
|
||||
// And now, ReactOS paged pool
|
||||
//
|
||||
BaseAddress = MmPagedPoolBase;
|
||||
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_PAGED_POOL | MEMORY_AREA_STATIC,
|
||||
&BaseAddress,
|
||||
MmPagedPoolSize,
|
||||
PAGE_READWRITE,
|
||||
&MArea,
|
||||
TRUE,
|
||||
0,
|
||||
BoundaryAddressMultiple);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
//
|
||||
// Next, the KPCR
|
||||
//
|
||||
|
@ -287,10 +272,6 @@ MiDbgDumpAddressSpace(VOID)
|
|||
MmSystemRangeStart,
|
||||
(ULONG_PTR)MmSystemRangeStart + MmBootImageSize,
|
||||
"Boot Loaded Image");
|
||||
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
||||
MmPagedPoolBase,
|
||||
(ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize,
|
||||
"Paged Pool");
|
||||
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
||||
MmPfnDatabase,
|
||||
(ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
|
||||
|
@ -389,80 +370,13 @@ MmInitSystem(IN ULONG Phase,
|
|||
//
|
||||
MiDbgReadyForPhysical = TRUE;
|
||||
#endif
|
||||
|
||||
/* Put the paged pool after the loaded modules */
|
||||
MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart +
|
||||
MmBootImageSize);
|
||||
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
|
||||
|
||||
|
||||
/* Intialize system memory areas */
|
||||
MiInitSystemMemoryAreas();
|
||||
|
||||
//
|
||||
// STEP 1: Allocate and free a single page, repeatedly
|
||||
// We should always get the same address back
|
||||
//
|
||||
if (1)
|
||||
{
|
||||
PULONG Test, OldTest;
|
||||
ULONG i;
|
||||
|
||||
OldTest = Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
|
||||
ASSERT(Test);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
MiFreePoolPages(Test);
|
||||
Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
|
||||
ASSERT(OldTest == Test);
|
||||
}
|
||||
MiFreePoolPages(Test);
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Allocate 2048 pages without freeing them
|
||||
// We should run out of space at 1024 pages, since we don't support
|
||||
// expansion yet.
|
||||
//
|
||||
if (1)
|
||||
{
|
||||
PULONG Test[2048];
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < 2048; i++)
|
||||
{
|
||||
Test[i] = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
|
||||
if (!Test[i])
|
||||
{
|
||||
ASSERT(i == 1024);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup
|
||||
//
|
||||
while (--i) if (Test[i]) MiFreePoolPages(Test[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 3: Allocate a page and touch it.
|
||||
// We should get an ARM3 page fault and it should handle the fault
|
||||
//
|
||||
if (1)
|
||||
{
|
||||
PULONG Test;
|
||||
|
||||
Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
|
||||
ASSERT(*Test == 0);
|
||||
MiFreePoolPages(Test);
|
||||
}
|
||||
|
||||
/* Dump the address space */
|
||||
MiDbgDumpAddressSpace();
|
||||
|
||||
/* Initialize paged pool */
|
||||
MmInitializePagedPool();
|
||||
|
||||
|
||||
/* Initialize working sets */
|
||||
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
|
||||
|
||||
|
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/pool.c
|
||||
* PURPOSE: Implements the kernel memory pool
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* Uncomment to enable pool overruns debugging. Don't forget to increase
|
||||
max pool sizes (MM_[NON]PAGED_POOL_SIZE) in include/internal/mm.h */
|
||||
//#define DEBUG_NPOOL
|
||||
//#define DEBUG_PPOOL
|
||||
|
||||
extern PVOID MiNonPagedPoolStart;
|
||||
extern ULONG MiNonPagedPoolLength;
|
||||
extern ULONG MmTotalPagedPoolQuota;
|
||||
extern ULONG MmTotalNonPagedPoolQuota;
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
ULONG NTAPI
|
||||
EiGetPagedPoolTag(IN PVOID Block);
|
||||
|
||||
ULONG NTAPI
|
||||
EiGetNonPagedPoolTag(IN PVOID Block);
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
ExAllocateArmPoolWithTag(POOL_TYPE PoolType,
|
||||
SIZE_T NumberOfBytes,
|
||||
ULONG Tag);
|
||||
|
||||
static PVOID NTAPI
|
||||
EiAllocatePool(POOL_TYPE PoolType,
|
||||
ULONG NumberOfBytes,
|
||||
ULONG Tag,
|
||||
PVOID Caller)
|
||||
{
|
||||
PVOID Block;
|
||||
PCHAR TagChars = (PCHAR)&Tag;
|
||||
|
||||
if (Tag == 0)
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x9b, PoolType, NumberOfBytes, (ULONG_PTR)Caller);
|
||||
if (Tag == ' GIB')
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x9c, PoolType, NumberOfBytes, (ULONG_PTR)Caller);
|
||||
|
||||
#define IS_LETTER_OR_DIGIT(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || ((c) >= '0' && (c) <= '9'))
|
||||
if (!IS_LETTER_OR_DIGIT(TagChars[0]) &&
|
||||
!IS_LETTER_OR_DIGIT(TagChars[1]) &&
|
||||
!IS_LETTER_OR_DIGIT(TagChars[2]) &&
|
||||
!IS_LETTER_OR_DIGIT(TagChars[3]))
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x9d, Tag, PoolType, (ULONG_PTR)Caller);
|
||||
|
||||
/* FIXME: Handle SESSION_POOL_MASK, VERIFIER_POOL_MASK, QUOTA_POOL_MASK */
|
||||
if (PoolType & PAGED_POOL_MASK)
|
||||
{
|
||||
if (KeGetCurrentIrql() > APC_LEVEL)
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x08, KeGetCurrentIrql(), PoolType, Tag);
|
||||
#ifdef DEBUG_PPOOL
|
||||
if (ExpIsPoolTagDebuggable(Tag))
|
||||
Block = ExpAllocateDebugPool(PoolType, NumberOfBytes, Tag, Caller, TRUE);
|
||||
else
|
||||
#endif
|
||||
Block = ExAllocatePagedPoolWithTag(PoolType, NumberOfBytes, Tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x08, KeGetCurrentIrql(), PoolType, Tag);
|
||||
#ifdef DEBUG_NPOOL
|
||||
if (ExpIsPoolTagDebuggable(Tag))
|
||||
Block = ExpAllocateDebugPool(PoolType, NumberOfBytes, Tag, Caller, TRUE);
|
||||
else
|
||||
#endif
|
||||
Block = ExAllocateArmPoolWithTag(PoolType, NumberOfBytes, Tag);
|
||||
}
|
||||
|
||||
if ((PoolType & MUST_SUCCEED_POOL_MASK) && !Block)
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x9a, PoolType, NumberOfBytes, Tag);
|
||||
return Block;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID NTAPI
|
||||
ExAllocatePool (POOL_TYPE PoolType, SIZE_T NumberOfBytes)
|
||||
/*
|
||||
* FUNCTION: Allocates pool memory of a specified type and returns a pointer
|
||||
* to the allocated block. This routine is used for general purpose allocation
|
||||
* of memory
|
||||
* ARGUMENTS:
|
||||
* PoolType
|
||||
* Specifies the type of memory to allocate which can be one
|
||||
* of the following:
|
||||
*
|
||||
* NonPagedPool
|
||||
* NonPagedPoolMustSucceed
|
||||
* NonPagedPoolCacheAligned
|
||||
* NonPagedPoolCacheAlignedMustS
|
||||
* PagedPool
|
||||
* PagedPoolCacheAligned
|
||||
*
|
||||
* NumberOfBytes
|
||||
* Specifies the number of bytes to allocate
|
||||
* RETURNS: The allocated block on success
|
||||
* NULL on failure
|
||||
*/
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
Block = EiAllocatePool(PoolType,
|
||||
NumberOfBytes,
|
||||
TAG_NONE,
|
||||
(PVOID)__builtin_return_address(0));
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
Block = EiAllocatePool(PoolType,
|
||||
NumberOfBytes,
|
||||
TAG_NONE,
|
||||
&ExAllocatePool);
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
return(Block);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID NTAPI
|
||||
ExAllocatePoolWithTag (POOL_TYPE PoolType, SIZE_T NumberOfBytes, ULONG Tag)
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
Block = EiAllocatePool(PoolType,
|
||||
NumberOfBytes,
|
||||
Tag,
|
||||
(PVOID)__builtin_return_address(0));
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
Block = EiAllocatePool(PoolType,
|
||||
NumberOfBytes,
|
||||
Tag,
|
||||
&ExAllocatePoolWithTag);
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
return(Block);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
#undef ExFreePool
|
||||
VOID NTAPI
|
||||
ExFreePool(IN PVOID Block)
|
||||
{
|
||||
ExFreePoolWithTag(Block, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ExFreeArmPoolWithTag(PVOID P,
|
||||
ULONG TagToFree);
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
ExFreePoolWithTag(
|
||||
IN PVOID Block,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
/* Check for paged pool */
|
||||
if (Block >= MmPagedPoolBase &&
|
||||
(char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize))
|
||||
{
|
||||
/* Validate tag */
|
||||
#ifndef DEBUG_PPOOL
|
||||
if (Tag != 0 && Tag != EiGetPagedPoolTag(Block))
|
||||
KeBugCheckEx(BAD_POOL_CALLER,
|
||||
0x0a,
|
||||
(ULONG_PTR)Block,
|
||||
EiGetPagedPoolTag(Block),
|
||||
Tag);
|
||||
#endif
|
||||
/* Validate IRQL */
|
||||
if (KeGetCurrentIrql() > APC_LEVEL)
|
||||
KeBugCheckEx(BAD_POOL_CALLER,
|
||||
0x09,
|
||||
KeGetCurrentIrql(),
|
||||
PagedPool,
|
||||
(ULONG_PTR)Block);
|
||||
|
||||
/* Free from paged pool */
|
||||
#ifdef DEBUG_PPOOL
|
||||
if (ExpIsPoolTagDebuggable(Tag))
|
||||
ExpFreeDebugPool(Block, TRUE);
|
||||
else
|
||||
#endif
|
||||
ExFreePagedPool(Block);
|
||||
}
|
||||
else if (Block) ExFreeArmPoolWithTag(Block, Tag);
|
||||
else
|
||||
{
|
||||
/* Only warn and break for NULL pointers */
|
||||
if (Block == NULL)
|
||||
{
|
||||
DPRINT1("Warning: Trying to free a NULL pointer!\n");
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Block was not inside any pool! */
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x42, (ULONG_PTR)Block, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,243 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/ppool.c
|
||||
* PURPOSE: Implements the paged pool
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||
* Royce Mitchell III
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#if defined (ALLOC_PRAGMA)
|
||||
#pragma alloc_text(INIT, MmInitializePagedPool)
|
||||
#endif
|
||||
|
||||
#undef ASSERT
|
||||
#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); }
|
||||
|
||||
// enable "magic"
|
||||
//#define R_MAGIC
|
||||
#define R_MUTEX FAST_MUTEX
|
||||
#define R_ACQUIRE_MUTEX(pool) /*DPRINT1("Acquiring PPool Mutex\n");*/ ExAcquireFastMutex(&pool->Mutex)
|
||||
#define R_RELEASE_MUTEX(pool) /*DPRINT1("Releasing PPool Mutex\n");*/ ExReleaseFastMutex(&pool->Mutex)
|
||||
#define R_PRINT_ADDRESS(addr) KeRosPrintAddress(addr)
|
||||
#define R_PANIC() KeBugCheck(MEMORY_MANAGEMENT)
|
||||
#define R_DEBUG DbgPrint
|
||||
|
||||
#ifdef _ARM_
|
||||
#define R_GET_STACK_FRAMES(ptr,cnt)
|
||||
#else
|
||||
#define R_GET_STACK_FRAMES(ptr,cnt) RtlWalkFrameChain((PVOID*)ptr,cnt, 0)
|
||||
#endif
|
||||
|
||||
#include "rpoolmgr.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
PVOID MmPagedPoolBase;
|
||||
ULONG MmPagedPoolSize;
|
||||
ULONG MmTotalPagedPoolQuota = 0; // TODO FIXME commented out until we use it
|
||||
static PR_POOL MmPagedPool = NULL;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
MmInitializePagedPool(VOID)
|
||||
{
|
||||
/*
|
||||
* We are still at a high IRQL level at this point so explicitly commit
|
||||
* the first page of the paged pool before writing the first block header.
|
||||
*/
|
||||
MmCommitPagedPoolAddress ( (PVOID)MmPagedPoolBase, FALSE );
|
||||
|
||||
MmPagedPool = RPoolInit ( MmPagedPoolBase,
|
||||
MmPagedPoolSize,
|
||||
MM_POOL_ALIGNMENT,
|
||||
MM_CACHE_LINE_SIZE,
|
||||
PAGE_SIZE );
|
||||
|
||||
ExInitializeFastMutex(&MmPagedPool->Mutex);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME INTERNAL
|
||||
* ExAllocatePagedPoolWithTag@12
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ARGUMENTS
|
||||
*
|
||||
* RETURN VALUE
|
||||
*/
|
||||
PVOID NTAPI
|
||||
ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
|
||||
IN ULONG NumberOfBytes,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
int align;
|
||||
|
||||
if ( NumberOfBytes >= PAGE_SIZE )
|
||||
align = 2;
|
||||
else if ( PoolType & CACHE_ALIGNED_POOL_MASK )
|
||||
align = 1;
|
||||
else
|
||||
align = 0;
|
||||
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
|
||||
|
||||
return RPoolAlloc ( MmPagedPool, NumberOfBytes, Tag, align );
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
ExFreePagedPool(IN PVOID Block)
|
||||
{
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
|
||||
RPoolFree ( MmPagedPool, Block );
|
||||
}
|
||||
|
||||
ULONG NTAPI
|
||||
EiGetPagedPoolTag(IN PVOID Block)
|
||||
{
|
||||
return RBodyToHdr(Block)->Tag;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PPOOL_UMODE_TEST
|
||||
|
||||
PVOID TestAlloc ( ULONG Bytes )
|
||||
{
|
||||
PVOID ret;
|
||||
|
||||
//printf ( "Allocating block: " ); RPoolStats ( MmPagedPool );
|
||||
//RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
|
||||
|
||||
ret = ExAllocatePagedPoolWithTag ( PagedPool, Bytes, 0 );
|
||||
|
||||
//printf ( "Block %x allocated: ", ret ); RPoolStats ( MmPagedPool );
|
||||
//RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TestFree ( PVOID ptr )
|
||||
{
|
||||
//printf ( "Freeing block %x: ", ptr ); RPoolStats ( MmPagedPool );
|
||||
//RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
|
||||
ExFreePagedPool(ptr);
|
||||
//printf ( "Block %x freed: ", ptr ); RPoolStats ( MmPagedPool );
|
||||
//RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#define COUNT 100
|
||||
int i, j;
|
||||
char* keepers[COUNT];
|
||||
char* trash[COUNT];
|
||||
int AllocSize[] = { 15, 31, 63, 127, 255, 511, 1023, 2047 };
|
||||
const int ALLOCS = sizeof(AllocSize) / sizeof(0[AllocSize]);
|
||||
ULONG dwStart;
|
||||
|
||||
MmPagedPoolSize = 1*1024*1024;
|
||||
MmPagedPoolBase = malloc ( MmPagedPoolSize );
|
||||
MmInitializePagedPool();
|
||||
|
||||
dwStart = GetTickCount();
|
||||
|
||||
printf ( "test #1 phase #1\n" );
|
||||
for ( i = 0; i < COUNT; i++ )
|
||||
{
|
||||
//printf ( "keeper %i) ", i );
|
||||
keepers[i] = TestAlloc ( AllocSize[i%ALLOCS] );
|
||||
if ( !keepers[i] ) printf ( "allocation failed\n" );
|
||||
//printf ( "trash %i) ", i );
|
||||
trash[i] = TestAlloc ( AllocSize[i%ALLOCS] );
|
||||
if ( !trash[i] ) printf ( "allocation failed\n" );
|
||||
}
|
||||
|
||||
printf ( "test #1 phase #2\n" );
|
||||
for ( i = 0; i < COUNT; i++ )
|
||||
{
|
||||
if ( i == 6 )
|
||||
i = i;
|
||||
//printf ( "%i) ", i );
|
||||
TestFree ( trash[i] );
|
||||
}
|
||||
|
||||
printf ( "test #1 phase #3\n" );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
//printf ( "%i) ", i );
|
||||
keepers[i] = TestAlloc ( 4096 );
|
||||
if ( !keepers[i] ) printf ( "allocation failed\n" );
|
||||
}
|
||||
|
||||
printf ( "test #1 phase #4\n" );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
//printf ( "%i) ", i );
|
||||
TestFree ( keepers[i] );
|
||||
}
|
||||
|
||||
printf ( "test #1 phase #5\n" );
|
||||
srand(1);
|
||||
for ( i = 0; i < COUNT; i++ )
|
||||
{
|
||||
//printf ( "%i) ", i );
|
||||
trash[i] = TestAlloc ( rand()%1024+1 );
|
||||
if ( !trash[i] ) printf ( "allocation failed\n" );
|
||||
}
|
||||
printf ( "test #1 phase #6\n" );
|
||||
for ( i = 0; i < 10000; i++ )
|
||||
{
|
||||
TestFree ( trash[i%COUNT] );
|
||||
trash[i%COUNT] = TestAlloc ( rand()%1024+1 );
|
||||
if ( !trash[i%COUNT] ) printf ( "allocation failed\n" );
|
||||
}
|
||||
printf ( "test #1 phase #7\n" );
|
||||
j = 0;
|
||||
for ( i = 0; i < COUNT; i++ )
|
||||
{
|
||||
if ( trash[i] )
|
||||
{
|
||||
TestFree ( trash[i] );
|
||||
++j;
|
||||
}
|
||||
}
|
||||
printf ( "test #1 phase #8 ( freed %i of %i trash )\n", j, COUNT );
|
||||
if ( !TestAlloc ( 2048 ) )
|
||||
printf ( "Couldn't allocate 2048 bytes after freeing up a whole bunch of blocks\n" );
|
||||
|
||||
free ( MmPagedPoolBase );
|
||||
|
||||
printf ( "test time: %lu\n", GetTickCount() - dwStart );
|
||||
|
||||
printf ( "test #2\n" );
|
||||
|
||||
MmPagedPoolSize = 1024;
|
||||
MmPagedPoolBase = malloc ( MmPagedPoolSize );
|
||||
MmInitializePagedPool();
|
||||
|
||||
TestAlloc ( 512 );
|
||||
i = RPoolLargestAllocPossible ( MmPagedPool, 0 );
|
||||
if ( !TestAlloc ( i ) )
|
||||
{
|
||||
printf ( "allocating last available block failed\n" );
|
||||
}
|
||||
|
||||
free ( MmPagedPoolBase );
|
||||
|
||||
printf ( "done!\n" );
|
||||
return 0;
|
||||
}
|
||||
#endif//PPOOL_UMODE_TEST
|
||||
|
||||
/* EOF */
|
File diff suppressed because it is too large
Load diff
|
@ -403,7 +403,6 @@
|
|||
</directory>
|
||||
<file>anonmem.c</file>
|
||||
<file>balance.c</file>
|
||||
<file>dbgpool.c</file>
|
||||
<file>freelist.c</file>
|
||||
<file>marea.c</file>
|
||||
<if property="_WINKD_" value ="1">
|
||||
|
@ -415,8 +414,6 @@
|
|||
<file>pagefile.c</file>
|
||||
<file>pageop.c</file>
|
||||
<file>pe.c</file>
|
||||
<file>pool.c</file>
|
||||
<file>ppool.c</file>
|
||||
<file>procsup.c</file>
|
||||
<file>region.c</file>
|
||||
<file>rmap.c</file>
|
||||
|
|
Loading…
Reference in a new issue