Author: ros-arm-bringup
Date: Sat Jan 2 17:17:48 2010
New Revision: 44885
URL:
http://svn.reactos.org/svn/reactos?rev=44885&view=rev
Log:
- 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.
Removed:
trunk/reactos/ntoskrnl/mm/dbgpool.c
trunk/reactos/ntoskrnl/mm/pool.c
trunk/reactos/ntoskrnl/mm/ppool.c
trunk/reactos/ntoskrnl/mm/rpoolmgr.h
Modified:
trunk/reactos/ntoskrnl/ex/sysinfo.c
trunk/reactos/ntoskrnl/mm/ARM3/expool.c
trunk/reactos/ntoskrnl/mm/mminit.c
trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Sat Jan 2 17:17:48 2010
@@ -594,7 +594,7 @@
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 */
Modified: trunk/reactos/ntoskrnl/mm/ARM3/expool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/expool.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] Sat Jan 2 17:17:48 2010
@@ -178,11 +178,14 @@
/* 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 @@
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 @@
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 @@
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);
}
/*
Removed: trunk/reactos/ntoskrnl/mm/dbgpool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/dbgpool.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/dbgpool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/dbgpool.c (removed)
@@ -1,134 +1,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(a)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 */
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Sat Jan 2 17:17:48 2010
@@ -199,21 +199,6 @@
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
//
BaseAddress = (PVOID)PCR;
@@ -287,10 +272,6 @@
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 @@
//
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);
Removed: trunk/reactos/ntoskrnl/mm/pool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/pool.c?rev=448…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/pool.c (removed)
@@ -1,236 +1,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(a)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 */
Removed: trunk/reactos/ntoskrnl/mm/ppool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ppool.c?rev=44…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ppool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ppool.c (removed)
@@ -1,243 +1,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(a)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 */
Removed: trunk/reactos/ntoskrnl/mm/rpoolmgr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/rpoolmgr.h?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/rpoolmgr.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/rpoolmgr.h (removed)
@@ -1,1060 +1,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/RPoolMgr.h
- * PURPOSE: A semi-generic reuseable Pool implementation
- * PROGRAMMER: Royce Mitchell III
- * UPDATE HISTORY:
- */
-
-#ifndef RPOOLMGR_H
-#define RPOOLMGR_H
-
-typedef unsigned long rulong;
-
-#define R_IS_POOL_PTR(pool,ptr) (((void*)(ULONG_PTR)(ptr) >= pool->UserBase)
&& ((ULONG_PTR)(ptr) < ((ULONG_PTR)pool->UserBase + pool->UserSize)))
-#define R_ASSERT_PTR(pool,ptr) ASSERT( R_IS_POOL_PTR(pool,ptr) )
-#define R_ASSERT_SIZE(pool,sz) ASSERT( sz > (sizeof(R_USED)+2*R_RZ) && sz
>= sizeof(R_FREE) && sz < pool->UserSize )
-
-#ifndef R_ROUND_UP
-#define R_ROUND_UP(x,s) ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
-#endif//R_ROUND_UP
-
-#ifndef R_ROUND_DOWN
-#define R_ROUND_DOWN(x,s) ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
-#endif//R_ROUND_DOWN
-
-#ifndef R_QUEMIN
-// R_QUEMIN is the minimum number of entries to keep in a que
-#define R_QUEMIN 0
-#endif//R_QUEMIN
-
-#ifndef R_QUECOUNT
-// 16, 32, 64, 128, 256, 512
-#define R_QUECOUNT 6
-#endif//R_QUECOUNT
-
-#ifndef R_RZ
-// R_RZ is the redzone size
-#define R_RZ 4
-#endif//R_RZ
-
-#ifndef R_RZ_LOVALUE
-#define R_RZ_LOVALUE 0x87
-#endif//R_RZ_LOVALUE
-
-#ifndef R_RZ_HIVALUE
-#define R_RZ_HIVALUE 0xA5
-#endif//R_RZ_HIVALUE
-
-#ifndef R_STACK
-// R_STACK is the number of stack entries to store in blocks for debug purposes
-#define R_STACK 6
-#else // R_STACK
-#if R_STACK > 0 && R_STACK < 6
-/* Increase the frame depth to get a reasonable back trace */
-#undef R_STACK
-#define R_STACK 6
-#endif // R_STACK > 0 && R_STACK < 6
-#endif//R_STACK
-
-#ifndef R_TAG
-// R_TAG do we keep track of tags on a per-memory block basis?
-#define R_TAG 0
-#endif//R_TAG
-
-#ifdef R_MAGIC
-# ifndef R_FREE_MAGIC
-# define R_FREE_MAGIC (rulong)(('F'<<0) + ('r'<<8) +
('E'<<16) + ('e'<<24))
-# endif//R_FREE_MAGIC
-# ifndef R_USED_MAGIC
-# define R_USED_MAGIC (rulong)(('u'<<0) + ('S'<<8) +
('e'<<16) + ('D'<<24))
-# endif//R_USED_MAGIC
-#endif//R_MAGIC
-
-// **IMPORTANT NOTE** Magic, PrevSize, Size and Status must be at same offset
-// in both the R_FREE and R_USED structures
-
-typedef struct _R_FREE
-{
-#ifdef R_MAGIC
- rulong FreeMagic;
-#endif//R_MAGIC
- rulong PrevSize : 30;
- rulong Status : 2;
- rulong Size;
-#if R_STACK
- ULONG_PTR LastOwnerStack[R_STACK];
-#endif//R_STACK
- struct _R_FREE* NextFree;
- struct _R_FREE* PrevFree;
-}
-R_FREE, *PR_FREE;
-
-typedef struct _R_USED
-{
-#ifdef R_MAGIC
- rulong UsedMagic;
-#endif//R_MAGIC
- rulong PrevSize : 30;
- rulong Status : 2;
- rulong Size;
-#if R_STACK
- ULONG_PTR LastOwnerStack[R_STACK];
-#endif//R_STACK
- struct _R_USED* NextUsed;
-#if R_RZ
- rulong UserSize; // how many bytes the user actually asked for...
-#endif//R_RZ
- rulong Tag;
-}
-R_USED, *PR_USED;
-
-typedef struct _R_QUE
-{
- rulong Count;
- PR_USED First, Last;
-}
-R_QUE, *PR_QUE;
-
-typedef struct _R_POOL
-{
- void* PoolBase;
- rulong PoolSize;
- void* UserBase;
- rulong UserSize;
- rulong Alignments[3];
- PR_FREE FirstFree, LastFree;
- R_QUE Que[R_QUECOUNT][3];
- R_MUTEX Mutex;
-}
-R_POOL, *PR_POOL;
-
-#if !R_STACK
-#define RiPrintLastOwner(Block)
-#else
-static void
-RiPrintLastOwner ( PR_USED Block )
-{
- int i;
- for ( i = 0; i < R_STACK; i++ )
- {
- if ( Block->LastOwnerStack[i] != 0xDEADBEEF )
- {
- R_DEBUG(" ");
- //if (!R_PRINT_ADDRESS ((PVOID)Block->LastOwnerStack[i]) )
- {
- R_DEBUG("<%X>", Block->LastOwnerStack[i] );
- }
- }
- }
-}
-#endif//R_STACK
-
-static int
-RQueWhich ( rulong size )
-{
- rulong que, quesize;
- for ( que=0, quesize=16; que < R_QUECOUNT; que++, quesize<<=1 )
- {
- if ( quesize >= size )
- {
- return que;
- }
- }
- return -1;
-}
-
-static void
-RQueInit ( PR_QUE que )
-{
- que->Count = 0;
- que->First = NULL;
- que->Last = NULL;
-}
-
-static void
-RQueAdd ( PR_QUE que, PR_USED Item )
-{
- ASSERT(Item);
- Item->Status = 2;
- Item->NextUsed = NULL;
- ++que->Count;
- if ( !que->Last )
- {
- que->First = que->Last = Item;
- return;
- }
- ASSERT(!que->Last->NextUsed);
- que->Last->NextUsed = Item;
- que->Last = Item;
-}
-
-static PR_USED
-RQueRemove ( PR_QUE que )
-{
- PR_USED Item;
-#if R_QUEMIN
- if ( que->count < R_QUEMIN )
- return NULL;
-#endif
- if ( !que->First )
- return NULL;
- Item = que->First;
- que->First = Item->NextUsed;
- if ( !--que->Count )
- {
- ASSERT ( !que->First );
- que->Last = NULL;
- }
- Item->Status = 0;
- return Item;
-}
-
-static void
-RPoolAddFree ( PR_POOL pool, PR_FREE Item )
-{
- ASSERT(pool);
- ASSERT(Item);
- if ( !pool->FirstFree )
- {
- pool->FirstFree = pool->LastFree = Item;
- Item->NextFree = NULL;
- }
- else
- {
- pool->FirstFree->PrevFree = Item;
- Item->NextFree = pool->FirstFree;
- pool->FirstFree = Item;
- }
- Item->PrevFree = NULL;
-}
-
-static void
-RPoolRemoveFree ( PR_POOL pool, PR_FREE Item )
-{
- ASSERT(pool);
- ASSERT(Item);
- if ( Item->NextFree )
- Item->NextFree->PrevFree = Item->PrevFree;
- else
- {
- ASSERT ( pool->LastFree == Item );
- pool->LastFree = Item->PrevFree;
- }
- if ( Item->PrevFree )
- Item->PrevFree->NextFree = Item->NextFree;
- else
- {
- ASSERT ( pool->FirstFree == Item );
- pool->FirstFree = Item->NextFree;
- }
-#if DBG
- Item->NextFree = Item->PrevFree = (PR_FREE)(ULONG_PTR)0xDEADBEEF;
-#endif//DBG
-}
-
-#if !R_STACK
-#define RFreeFillStack(free)
-#define RUsedFillStack(used)
-#else
-static void
-RFreeFillStack ( PR_FREE free )
-{
- int i;
- ULONG stack[R_STACK+3]; // need to skip 3 known levels of stack trace
- memset ( stack, 0xCD, sizeof(stack) );
- R_GET_STACK_FRAMES ( stack, R_STACK+3 );
- for ( i = 0; i < R_STACK; i++ )
- free->LastOwnerStack[i] = stack[i+3];
-}
-
-static void
-RUsedFillStack ( PR_USED used )
-{
- int i;
- ULONG stack[R_STACK+2]; // need to skip 2 known levels of stack trace
- memset ( stack, 0xCD, sizeof(stack) );
- R_GET_STACK_FRAMES ( stack, R_STACK+2 );
- for ( i = 0; i < R_STACK; i++ )
- used->LastOwnerStack[i] = stack[i+2];
-}
-#endif
-
-static PR_FREE
-RFreeInit ( void* memory )
-{
- PR_FREE block = (PR_FREE)memory;
-#if R_FREEMAGIC
- block->FreeMagic = R_FREE_MAGIC;
-#endif//R_FREEMAGIC
- block->Status = 0;
- RFreeFillStack ( block );
-#if DBG
- block->PrevFree = block->NextFree = (PR_FREE)(ULONG_PTR)0xDEADBEEF;
-#endif//DBG
- return block;
-}
-
-PR_POOL
-RPoolInit ( void* PoolBase, rulong PoolSize, int align1, int align2, int align3 )
-{
- int align, que;
- PR_POOL pool = (PR_POOL)PoolBase;
-
- pool->PoolBase = PoolBase;
- pool->PoolSize = PoolSize;
- pool->UserBase = (char*)pool->PoolBase + sizeof(R_POOL);
- pool->UserSize = PoolSize - sizeof(R_POOL);
- pool->Alignments[0] = align1;
- pool->Alignments[1] = align2;
- pool->Alignments[2] = align3;
- pool->FirstFree = pool->LastFree = NULL;
-
- RPoolAddFree ( pool,
- RFreeInit ( pool->UserBase ));
-
- pool->FirstFree->PrevSize = 0;
- pool->FirstFree->Size = pool->UserSize;
-
- for ( que = 0; que < R_QUECOUNT; que++ )
- {
- for ( align = 0; align < 3; align++ )
- {
- RQueInit ( &pool->Que[que][align] );
- }
- }
- return pool;
-}
-
-#if R_RZ
-static const char*
-RFormatTag ( rulong Tag, char* buf )
-{
- int i;
- *(rulong*)&buf[0] = Tag;
- buf[4] = 0;
- for ( i = 0; i < 4; i++ )
- {
- if ( !buf[i] )
- buf[i] = ' ';
- }
- return buf;
-}
-#endif
-
-#if !R_RZ
-#define RUsedRedZoneCheck(pUsed,Addr,file,line, printzone)
-#else//R_RZ
-static void
-RiBadBlock ( PR_USED pUsed, char* Addr, const char* violation, const char* file, int
line, int printzone )
-{
- char tag[5];
- unsigned int i;
-
- R_DEBUG("%s(%i): %s detected for paged pool address 0x%x\n",
- file, line, violation, Addr );
-
-#ifdef R_MAGIC
- R_DEBUG ( "UsedMagic 0x%x, ", pUsed->UsedMagic );
-#endif//R_MAGIC
- R_DEBUG ( "Tag %s(%X), Size %i, UserSize %i",
- RFormatTag(pUsed->Tag,tag),
- pUsed->Tag,
- pUsed->Size,
- pUsed->UserSize );
-
- if ( printzone )
- {
- unsigned char* HiZone = (unsigned char*)Addr + pUsed->UserSize;
- unsigned char* LoZone = (unsigned char*)Addr - R_RZ; // this is to simplify indexing
below...
- R_DEBUG ( ", LoZone " );
- for ( i = 0; i < R_RZ; i++ )
- R_DEBUG ( "%02x", LoZone[i] );
- R_DEBUG ( ", HiZone " );
- for ( i = 0; i < R_RZ; i++ )
- R_DEBUG ( "%02x", HiZone[i] );
- }
- R_DEBUG ( "\n" );
-
- R_DEBUG ( "First few Stack Frames:" );
- RiPrintLastOwner ( pUsed );
- R_DEBUG ( "\n" );
-
- R_DEBUG ( "Contents of Block:\n" );
- for ( i = 0; i < 8*16 && i < pUsed->UserSize; i += 16 )
- {
- int j;
- R_DEBUG ( "%04X ", i );
- for ( j = 0; j < 16; j++ )
- {
- if ( i+j < pUsed->UserSize )
- {
- R_DEBUG ( "%02X ", (unsigned)(unsigned char)Addr[i+j] );
- }
- else
- {
- R_DEBUG ( " " );
- }
- }
- R_DEBUG(" ");
- for ( j = 0; j < 16; j++ )
- {
- if ( i+j < pUsed->UserSize )
- {
- char c = Addr[i+j];
- if ( c < 0x20 || c > 0x7E )
- c = '.';
- R_DEBUG ( "%c", c );
- }
- else
- {
- R_DEBUG ( " " );
- }
- }
- R_DEBUG("\n");
- }
- R_PANIC();
-}
-static void
-RUsedRedZoneCheck ( PR_POOL pool, PR_USED pUsed, char* Addr, const char* file, int line
)
-{
- int i;
- unsigned char *LoZone, *HiZone;
- int bLow = 1;
- int bHigh = 1;
-
- ASSERT ( Addr >= (char*)pool->UserBase && Addr <
((char*)pool->UserBase + pool->UserSize - 16) );
-#ifdef R_MAGIC
- if ( pUsed->UsedMagic == R_FREE_MAGIC )
- {
- pUsed->UserSize = 0; // just to keep from confusion, MmpBadBlock() doesn't
return...
- RiBadBlock ( pUsed, Addr, "double-free", file, line, 0 );
- }
- if ( pUsed->UsedMagic != R_USED_MAGIC )
- {
- RiBadBlock ( pUsed, Addr, "bad magic", file, line, 0 );
- }
-#endif//R_MAGIC
- switch ( pUsed->Status )
- {
- case 0: // freed into main pool
- case 2: // in ques
- RiBadBlock ( pUsed, Addr, "double-free", file, line, 0 );
- // no need for break here - RiBadBlock doesn't return
- case 1: // allocated - this is okay
- break;
- default:
- RiBadBlock ( pUsed, Addr, "corrupt status", file, line, 0 );
- }
- if ( pUsed->Status != 1 )
- {
- RiBadBlock ( pUsed, Addr, "double-free", file, line, 0 );
- }
- if ( pUsed->Size > pool->PoolSize || pUsed->Size == 0 )
- {
- RiBadBlock ( pUsed, Addr, "invalid size", file, line, 0 );
- }
- if ( pUsed->UserSize > pool->PoolSize || pUsed->UserSize == 0 )
- {
- RiBadBlock ( pUsed, Addr, "invalid user size", file, line, 0 );
- }
- HiZone = (unsigned char*)Addr + pUsed->UserSize;
- LoZone = (unsigned char*)Addr - R_RZ; // this is to simplify indexing below...
- for ( i = 0; i < R_RZ && bLow && bHigh; i++ )
- {
- bLow = bLow && ( LoZone[i] == R_RZ_LOVALUE );
- bHigh = bHigh && ( HiZone[i] == R_RZ_HIVALUE );
- }
- if ( !bLow || !bHigh )
- {
- const char* violation = "High and Low-side redzone overwrite";
- if ( bHigh ) // high is okay, so it was just low failed
- violation = "Low-side redzone overwrite";
- else if ( bLow ) // low side is okay, so it was just high failed
- violation = "High-side redzone overwrite";
- RiBadBlock ( pUsed, Addr, violation, file, line, 1 );
- }
-}
-#endif//R_RZ
-
-PR_FREE
-RPreviousBlock ( PR_FREE Block )
-{
- if ( Block->PrevSize > 0 )
- return (PR_FREE)( (char*)Block - Block->PrevSize );
- return NULL;
-}
-
-PR_FREE
-RNextBlock ( PR_POOL pool, PR_FREE Block )
-{
- PR_FREE NextBlock = (PR_FREE)( (char*)Block + Block->Size );
- if ( (char*)NextBlock >= (char*)pool->UserBase + pool->UserSize )
- NextBlock = NULL;
- return NextBlock;
-}
-
-static __inline void*
-RHdrToBody ( void* blk )
-/*
- * FUNCTION: Translate a block header address to the corresponding block
- * address (internal)
- */
-{
- return ( (void *) ((char*)blk + sizeof(R_USED) + R_RZ) );
-}
-
-static __inline PR_USED
-RBodyToHdr ( void* addr )
-{
- return (PR_USED)
- ( ((char*)addr) - sizeof(R_USED) - R_RZ );
-}
-
-static int
-RiInFreeChain ( PR_POOL pool, PR_FREE Block )
-{
- PR_FREE Free;
- Free = pool->FirstFree;
- if ( Free == Block )
- return 1;
- while ( Free != Block )
- {
- Free = Free->NextFree;
- if ( !Free )
- return 0;
- }
- return 1;
-}
-
-static void
-RPoolRedZoneCheck ( PR_POOL pool, const char* file, int line )
-{
- {
- PR_USED Block = (PR_USED)pool->UserBase;
- PR_USED NextBlock;
-
- for ( ;; )
- {
- switch ( Block->Status )
- {
- case 0: // block is in chain
- ASSERT ( RiInFreeChain ( pool, (PR_FREE)Block ) );
- break;
- case 1: // block is allocated
- RUsedRedZoneCheck ( pool, Block, RHdrToBody(Block), file, line );
- break;
- case 2: // block is in que
- // nothing to verify here yet
- break;
- default:
- ASSERT ( !"invalid status in memory block found in pool!" );
- }
- NextBlock = (PR_USED)RNextBlock(pool,(PR_FREE)Block);
- if ( !NextBlock )
- break;
- ASSERT ( NextBlock->PrevSize == Block->Size );
- Block = NextBlock;
- }
- }
- {
- // now let's step through the list of free pointers and verify
- // each one can be found by size-jumping...
- PR_FREE Free = (PR_FREE)pool->FirstFree;
- while ( Free )
- {
- PR_FREE NextFree = (PR_FREE)pool->UserBase;
- if ( Free != NextFree )
- {
- while ( NextFree != Free )
- {
- NextFree = RNextBlock ( pool, NextFree );
- ASSERT(NextFree);
- }
- }
- Free = Free->NextFree;
- }
- }
-}
-
-static void
-RSetSize ( PR_POOL pool, PR_FREE Block, rulong NewSize, PR_FREE NextBlock )
-{
- R_ASSERT_PTR(pool,Block);
- ASSERT ( NewSize < pool->UserSize );
- ASSERT ( NewSize >= sizeof(R_FREE) );
- Block->Size = NewSize;
- if ( !NextBlock )
- NextBlock = RNextBlock ( pool, Block );
- if ( NextBlock )
- NextBlock->PrevSize = NewSize;
-}
-
-static PR_FREE
-RFreeSplit ( PR_POOL pool, PR_FREE Block, rulong NewSize )
-{
- PR_FREE NewBlock = (PR_FREE)((char*)Block + NewSize);
- RSetSize ( pool, NewBlock, Block->Size - NewSize, NULL );
- RSetSize ( pool, Block, NewSize, NewBlock );
- RFreeInit ( NewBlock );
- RPoolAddFree ( pool, NewBlock );
- return NewBlock;
-}
-
-static void
-RFreeMerge ( PR_POOL pool, PR_FREE First, PR_FREE Second )
-{
- ASSERT ( RPreviousBlock(Second) == First );
- ASSERT ( First->Size == Second->PrevSize );
- RPoolRemoveFree ( pool, Second );
- RSetSize ( pool, First, First->Size + Second->Size, NULL );
-}
-
-static void
-RPoolReclaim ( PR_POOL pool, PR_FREE FreeBlock )
-{
- PR_FREE NextBlock, PreviousBlock;
-
- RFreeInit ( FreeBlock );
- RPoolAddFree ( pool, FreeBlock );
-
- // TODO FIXME - don't merge and always insert freed blocks at the end for debugging
purposes...
-
- /*
- * If the next block is immediately adjacent to the newly freed one then
- * merge them.
- * PLEASE DO NOT WIPE OUT 'MAGIC' OR 'LASTOWNER' DATA FOR MERGED FREE
BLOCKS
- */
- NextBlock = RNextBlock ( pool, FreeBlock );
- if ( NextBlock != NULL && !NextBlock->Status )
- {
- RFreeMerge ( pool, FreeBlock, NextBlock );
- }
-
- /*
- * If the previous block is adjacent to the newly freed one then
- * merge them.
- * PLEASE DO NOT WIPE OUT 'MAGIC' OR 'LASTOWNER' DATA FOR MERGED FREE
BLOCKS
- */
- PreviousBlock = RPreviousBlock ( FreeBlock );
- if ( PreviousBlock != NULL && !PreviousBlock->Status )
- {
- RFreeMerge ( pool, PreviousBlock, FreeBlock );
- }
-}
-
-static void
-RiUsedInit ( PR_USED Block, rulong Tag )
-{
- Block->Status = 1;
- RUsedFillStack ( Block );
-#ifdef R_MAGIC
- Block->UsedMagic = R_USED_MAGIC;
-#endif//R_MAGIC
- //ASSERT_SIZE ( Block->Size );
-
- // now add the block to the used block list
-#if DBG
- Block->NextUsed = (PR_USED)(ULONG_PTR)0xDEADBEEF;
-#endif//R_USED_LIST
-
- Block->Tag = Tag;
-}
-
-#if !R_RZ
-#define RiUsedInitRedZone(Block,UserSize)
-#else//R_RZ
-static void
-RiUsedInitRedZone ( PR_USED Block, rulong UserSize )
-{
- // write out buffer-overrun detection bytes
- char* Addr = (char*)RHdrToBody(Block);
- Block->UserSize = UserSize;
- memset ( Addr - R_RZ, R_RZ_LOVALUE, R_RZ );
- memset ( Addr + Block->UserSize, R_RZ_HIVALUE, R_RZ );
-#if DBG
- memset ( Addr, 0xCD, UserSize );
-#endif//DBG
-}
-#endif//R_RZ
-
-static void*
-RPoolAlloc ( PR_POOL pool, rulong NumberOfBytes, rulong Tag, rulong align )
-{
- PR_USED NewBlock;
- PR_FREE BestBlock,
- NextBlock,
- PreviousBlock,
- BestPreviousBlock,
- CurrentBlock;
- void* BestAlignedAddr;
- int que,
- queBytes = NumberOfBytes;
- rulong BlockSize,
- Alignment;
- int que_reclaimed = 0;
-
- ASSERT ( pool );
- ASSERT ( align < 3 );
-
- R_ACQUIRE_MUTEX(pool);
-
- if ( !NumberOfBytes )
- {
- R_DEBUG("0 bytes requested - initiating pool verification\n");
- RPoolRedZoneCheck ( pool, __FILE__, __LINE__ );
- R_RELEASE_MUTEX(pool);
- return NULL;
- }
- if ( NumberOfBytes > pool->PoolSize )
- {
- if ( R_IS_POOL_PTR(pool,NumberOfBytes) )
- {
- R_DEBUG("red zone verification requested for block 0x%X\n", NumberOfBytes
);
- RUsedRedZoneCheck(pool,RBodyToHdr((void*)(ULONG_PTR)NumberOfBytes),
(char*)(ULONG_PTR)NumberOfBytes, __FILE__, __LINE__ );
- R_RELEASE_MUTEX(pool);
- return NULL;
- }
- R_DEBUG("Invalid allocation request: %i bytes\n", NumberOfBytes );
- R_RELEASE_MUTEX(pool);
- return NULL;
- }
-
- que = RQueWhich ( NumberOfBytes );
- if ( que >= 0 )
- {
- if ( (NewBlock = RQueRemove ( &pool->Que[que][align] )) )
- {
- RiUsedInit ( NewBlock, Tag );
- RiUsedInitRedZone ( NewBlock, NumberOfBytes );
- R_RELEASE_MUTEX(pool);
- return RHdrToBody(NewBlock);
- }
- queBytes = 16 << que;
- }
-
- /*
- * Calculate the total number of bytes we will need.
- */
- BlockSize = queBytes + sizeof(R_USED) + 2*R_RZ;
- if (BlockSize < sizeof(R_FREE))
- {
- /* At least we need the size of the free block header. */
- BlockSize = sizeof(R_FREE);
- }
-
-try_again:
- /*
- * Find the best-fitting block.
- */
- BestBlock = NULL;
- Alignment = pool->Alignments[align];
- PreviousBlock = NULL;
- BestPreviousBlock = NULL,
- CurrentBlock = pool->FirstFree;
- BestAlignedAddr = NULL;
-
- while ( CurrentBlock != NULL )
- {
- PVOID Addr = RHdrToBody(CurrentBlock);
- PVOID CurrentBlockEnd = (char*)CurrentBlock + CurrentBlock->Size;
- /* calculate last size-aligned address available within this block */
- PVOID AlignedAddr = R_ROUND_DOWN((char*)CurrentBlockEnd-queBytes-R_RZ, Alignment);
- ASSERT ( (char*)AlignedAddr+queBytes+R_RZ <= (char*)CurrentBlockEnd );
-
- /* special case, this address is already size-aligned, and the right size */
- if ( Addr == AlignedAddr )
- {
- BestAlignedAddr = AlignedAddr;
- BestPreviousBlock = PreviousBlock;
- BestBlock = CurrentBlock;
- break;
- }
- // if we carve out a size-aligned block... is it still past the end of this
- // block's free header?
- else if ( (char*)RBodyToHdr(AlignedAddr)
- >= (char*)CurrentBlock+sizeof(R_FREE) )
- {
- /*
- * there's enough room to allocate our size-aligned memory out
- * of this block, see if it's a better choice than any previous
- * finds
- */
- if ( BestBlock == NULL
- || BestBlock->Size > CurrentBlock->Size )
- {
- BestAlignedAddr = AlignedAddr;
- BestPreviousBlock = PreviousBlock;
- BestBlock = CurrentBlock;
- }
- }
-
- PreviousBlock = CurrentBlock;
- CurrentBlock = CurrentBlock->NextFree;
- }
-
- /*
- * We didn't find anything suitable at all.
- */
- if (BestBlock == NULL)
- {
- if ( !que_reclaimed )
- {
- // reclaim que
- int i, j;
- for ( i = 0; i < R_QUECOUNT; i++ )
- {
- for ( j = 0; j < 3; j++ )
- {
- while ( (BestBlock = (PR_FREE)RQueRemove ( &pool->Que[i][j] )) )
- {
- RPoolReclaim ( pool, BestBlock );
- }
- }
- }
-
- que_reclaimed = 1;
- goto try_again;
- }
- DPRINT1("Trying to allocate %lu bytes from paged pool - nothing suitable found,
returning NULL\n",
- queBytes );
- R_RELEASE_MUTEX(pool);
- return NULL;
- }
- /*
- * we found a best block. If Addr isn't already aligned, we've pre-qualified
that
- * there's room at the beginning of the block for a free block...
- */
- {
- void* Addr = RHdrToBody(BestBlock);
- if ( BestAlignedAddr != Addr )
- {
- PR_FREE NewFreeBlock = RFreeSplit (
- pool,
- BestBlock,
- (char*)RBodyToHdr(BestAlignedAddr) - (char*)BestBlock );
- ASSERT ( BestAlignedAddr > Addr );
-
- //DPRINT ( "breaking off preceding bytes into their own block...\n" );
- /*DPRINT ( "NewFreeBlock 0x%x Size %lu (Old Block's new size %lu) NextFree
0x%x\n",
- NewFreeBlock, NewFreeBlock->Size, BestBlock->Size, BestBlock->NextFree );*/
-
- /* we want the following code to use our size-aligned block */
- BestPreviousBlock = BestBlock;
- BestBlock = NewFreeBlock;
-
- //VerifyPagedPool();
- }
- }
- /*
- * Is there enough space to create a second block from the unused portion.
- */
- if ( (BestBlock->Size - BlockSize) > sizeof(R_FREE) )
- {
- /*DPRINT("BestBlock 0x%x Size 0x%x BlockSize 0x%x NewSize 0x%x\n",
- BestBlock, BestBlock->Size, BlockSize, NewSize );*/
-
- /*
- * Create the new free block.
- */
- NextBlock = RFreeSplit ( pool, BestBlock, BlockSize );
- //ASSERT_SIZE ( NextBlock->Size );
- }
- /*
- * Remove the selected block from the list of free blocks.
- */
- //DPRINT ( "Removing selected block from free block list\n" );
- RPoolRemoveFree ( pool, BestBlock );
- /*
- * Create the new used block header.
- */
- NewBlock = (PR_USED)BestBlock;
- RiUsedInit ( NewBlock, Tag );
-
- /* RtlZeroMemory(RHdrToBody(NewBlock), NumberOfBytes);*/
-
- RiUsedInitRedZone ( NewBlock, NumberOfBytes );
- R_RELEASE_MUTEX(pool);
-
- return RHdrToBody(NewBlock);
-}
-
-static void
-RPoolFree ( PR_POOL pool, void* Addr )
-{
- PR_USED UsedBlock;
- rulong UsedSize;
- PR_FREE FreeBlock;
- rulong UserSize;
- int que;
-
- ASSERT(pool);
- if ( !Addr )
- {
- R_DEBUG("Attempt to free NULL ptr, initiating Red Zone Check\n" );
- R_ACQUIRE_MUTEX(pool);
- RPoolRedZoneCheck ( pool, __FILE__, __LINE__ );
- R_RELEASE_MUTEX(pool);
- return;
- }
- R_ASSERT_PTR(pool,Addr);
-
- UsedBlock = RBodyToHdr(Addr);
- UsedSize = UsedBlock->Size;
- FreeBlock = (PR_FREE)UsedBlock;
-#if R_RZ
- UserSize = UsedBlock->UserSize;
-#else
- UserSize = UsedSize - sizeof(R_USED) - 2*R_RZ;
-#endif//R_RZ
-
- RUsedRedZoneCheck ( pool, UsedBlock, Addr, __FILE__, __LINE__ );
-
-#if R_RZ
- memset ( Addr, 0xCD, UsedBlock->UserSize );
-#endif
-
- que = RQueWhich ( UserSize );
- if ( que >= 0 )
- {
- int queBytes = 16 << que;
- ASSERT( (rulong)queBytes >= UserSize );
- if ( que >= 0 )
- {
- int align = 0;
- if ( R_ROUND_UP(Addr,pool->Alignments[2]) == Addr )
- align = 2;
- else if ( R_ROUND_UP(Addr,pool->Alignments[1]) == Addr )
- align = 1;
- R_ACQUIRE_MUTEX(pool);
- RQueAdd ( &pool->Que[que][align], UsedBlock );
- R_RELEASE_MUTEX(pool);
- return;
- }
- }
-
- R_ACQUIRE_MUTEX(pool);
- RPoolReclaim ( pool, FreeBlock );
- R_RELEASE_MUTEX(pool);
-}
-
-#if 0
-static void
-RPoolDumpByTag ( PR_POOL pool, rulong Tag )
-{
- PR_USED Block = (PR_USED)pool->UserBase;
- PR_USED NextBlock;
- int count = 0;
- char tag[5];
-
- // TODO FIXME - should we validate params or ASSERT_IRQL?
- R_DEBUG ( "PagedPool Dump by tag '%s'\n", RFormatTag(Tag,tag) );
- R_DEBUG ( " -BLOCK-- --SIZE--\n" );
-
- R_ACQUIRE_MUTEX(pool);
- for ( ;; )
- {
- if ( Block->Status == 1 && Block->Tag == Tag )
- {
- R_DEBUG ( " %08X %08X\n", Block, Block->Size );
- ++count;
- }
- NextBlock = (PR_USED)RNextBlock(pool,(PR_FREE)Block);
- if ( !NextBlock )
- break;
- ASSERT ( NextBlock->PrevSize == Block->Size );
- Block = NextBlock;
- }
- R_RELEASE_MUTEX(pool);
-
- R_DEBUG ( "Entries found for tag '%s': %i\n", tag, count );
-}
-#endif
-
-rulong
-RPoolQueryTag ( void* Addr )
-{
- PR_USED Block = RBodyToHdr(Addr);
- // TODO FIXME - should we validate params?
-#ifdef R_MAGIC
- if ( Block->UsedMagic != R_USED_MAGIC )
- return 0xDEADBEEF;
-#endif//R_MAGIC
- if ( Block->Status != 1 )
- return 0xDEADBEEF;
- return Block->Tag;
-}
-
-void
-RPoolStats ( PR_POOL pool )
-{
- int free=0, used=0, qued=0;
- PR_USED Block = (PR_USED)pool->UserBase;
-
- R_ACQUIRE_MUTEX(pool);
- while ( Block )
- {
- switch ( Block->Status )
- {
- case 0:
- ++free;
- break;
- case 1:
- ++used;
- break;
- case 2:
- ++qued;
- break;
- default:
- ASSERT ( !"Invalid Status for Block in pool!" );
- }
- Block = (PR_USED)RNextBlock(pool,(PR_FREE)Block);
- }
- R_RELEASE_MUTEX(pool);
-
- R_DEBUG ( "Pool Stats: Free=%i, Used=%i, Qued=%i, Total=%i\n", free, used,
qued, (free+used+qued) );
-}
-
-#ifdef R_LARGEST_ALLOC_POSSIBLE
-static rulong
-RPoolLargestAllocPossible ( PR_POOL pool, int align )
-{
- int Alignment = pool->Alignments[align];
- rulong LargestUserSize = 0;
- PR_FREE Block = (PR_FREE)pool->UserBase;
- while ( Block )
- {
- if ( Block->Status != 1 )
- {
- void* Addr, *AlignedAddr;
- rulong BlockMaxUserSize;
- int cue, cueBytes;
-
- Addr = (char*)Block + sizeof(R_USED) + R_RZ;
- AlignedAddr = R_ROUND_UP(Addr,Alignment);
- if ( Addr != AlignedAddr )
- Addr = R_ROUND_UP((char*)Block + sizeof(R_FREE) + sizeof(R_USED) + R_RZ, Alignment
);
- BlockMaxUserSize = (char*)Block + Block->Size - (char*)Addr - R_RZ;
- cue = RQueWhich ( BlockMaxUserSize );
- if ( cue >= 0 )
- {
- cueBytes = 16 << cue;
- if ( cueBytes > BlockMaxUserSize );
- {
- if ( !cue )
- BlockMaxUserSize = 0;
- else
- BlockMaxUserSize = 16 << (cue-1);
- }
- }
- if ( BlockMaxUserSize > LargestUserSize )
- LargestUserSize = BlockMaxUserSize;
- }
- Block = RNextBlock ( pool, Block );
- }
- return LargestUserSize;
-}
-#endif//R_LARGEST_ALLOC_POSSIBLE
-
-#endif//RPOOLMGR_H
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Sat Jan 2 17:17:48 2010
@@ -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>