Merge adjacent free blocks in the non-paged pool

Don't print the timer tick count to the screen

svn path=/trunk/; revision=1690
This commit is contained in:
David Welch 2001-03-14 23:19:14 +00:00
parent d12635ff66
commit 6fc1bdc912
5 changed files with 175 additions and 134 deletions

View file

@ -78,7 +78,7 @@ typedef struct _KTRAP_FRAME
USHORT Reserved9; USHORT Reserved9;
} KTRAP_FRAME, *PKTRAP_FRAME; } KTRAP_FRAME, *PKTRAP_FRAME;
VOID KiUpdateSystemTime (VOID); VOID KiUpdateSystemTime (KIRQL oldIrql);
VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait); VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait);
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait); VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait);

View file

@ -1,4 +1,4 @@
/* $Id: irq.c,v 1.6 2001/03/07 16:48:43 dwelch Exp $ /* $Id: irq.c,v 1.7 2001/03/14 23:19:14 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -153,12 +153,12 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
__asm__("sti\n\t"); __asm__("sti\n\t");
if (irq==0) if (irq==0)
{ {
KiUpdateSystemTime(); KiUpdateSystemTime(old_level);
} }
else else
{ {
DPRINT("KiInterruptDispatch(irq %d)\n",irq); DPRINT("KiInterruptDispatch(irq %d)\n",irq);
/* /*
* Iterate the list until one of the isr tells us its device interrupted * Iterate the list until one of the isr tells us its device interrupted
*/ */

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.40 2001/03/14 00:21:22 dwelch Exp $ /* $Id: timer.c,v 1.41 2001/03/14 23:19:14 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -427,7 +427,7 @@ KeExpireTimers(PKDPC Dpc,
VOID VOID
KiUpdateSystemTime (VOID) KiUpdateSystemTime (KIRQL oldIrql)
/* /*
* FUNCTION: Handles a timer interrupt * FUNCTION: Handles a timer interrupt
*/ */
@ -450,25 +450,15 @@ KiUpdateSystemTime (VOID)
* Display the tick count in the top left of the screen as a debugging * Display the tick count in the top left of the screen as a debugging
* aid * aid
*/ */
switch (KiTimerTicks % 4) vidmem[0] = ' ';
if (oldIrql < DISPATCH_LEVEL)
{ {
case 0: vidmem[1] = 0x17;
vidmem[0] = '|'; }
break; else
{
case 1: vidmem[1] = 0x27;
vidmem[0] = '/';
break;
case 2:
vidmem[0] = '-';
break;
case 3:
vidmem[0] = '\\';
break;
} }
vidmem[1] = 0x7;
/* /*
* Queue a DPC that will expire timers * Queue a DPC that will expire timers

View file

@ -1,4 +1,4 @@
/* $Id: kmap.c,v 1.6 2001/02/10 22:51:10 dwelch Exp $ /* $Id: kmap.c,v 1.7 2001/03/14 23:19:14 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -27,10 +27,10 @@
* One bit for each page in the kmalloc region * One bit for each page in the kmalloc region
* If set then the page is used by a kmalloc block * If set then the page is used by a kmalloc block
*/ */
static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,}; static unsigned int AllocMap[ALLOC_MAP_SIZE/32]={0,};
static KSPIN_LOCK AllocMapLock; static KSPIN_LOCK AllocMapLock;
static PVOID kernel_pool_base; static PVOID NonPagedPoolBase;
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
@ -38,14 +38,14 @@ VOID
ExUnmapPage(PVOID Addr) ExUnmapPage(PVOID Addr)
{ {
KIRQL oldIrql; KIRQL oldIrql;
ULONG i = (Addr - kernel_pool_base) / PAGESIZE; ULONG i = (Addr - NonPagedPoolBase) / PAGESIZE;
DPRINT("ExUnmapPage(Addr %x)\n",Addr); DPRINT("ExUnmapPage(Addr %x)\n",Addr);
DPRINT("i %x\n",i); DPRINT("i %x\n",i);
KeAcquireSpinLock(&AllocMapLock, &oldIrql); KeAcquireSpinLock(&AllocMapLock, &oldIrql);
MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE); MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE);
clear_bit(i%32, &alloc_map[i/32]); clear_bit(i%32, &AllocMap[i/32]);
KeReleaseSpinLock(&AllocMapLock, oldIrql); KeReleaseSpinLock(&AllocMapLock, oldIrql);
} }
@ -55,7 +55,6 @@ ExAllocatePage(VOID)
ULONG PhysPage; ULONG PhysPage;
PhysPage = (ULONG)MmAllocPage(0); PhysPage = (ULONG)MmAllocPage(0);
DPRINT("Allocated page %x\n",PhysPage);
if (PhysPage == 0) if (PhysPage == 0)
{ {
return(NULL); return(NULL);
@ -75,11 +74,11 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
KeAcquireSpinLock(&AllocMapLock, &oldlvl); KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i=1; i<ALLOC_MAP_SIZE;i++) for (i=1; i<ALLOC_MAP_SIZE;i++)
{ {
if (!test_bit(i%32,&alloc_map[i/32])) if (!test_bit(i%32,&AllocMap[i/32]))
{ {
DPRINT("i %x\n",i); DPRINT("i %x\n",i);
set_bit(i%32,&alloc_map[i/32]); set_bit(i%32,&AllocMap[i/32]);
addr = (ULONG)(kernel_pool_base + (i*PAGESIZE)); addr = (ULONG)(NonPagedPoolBase + (i*PAGESIZE));
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)addr, (PVOID)addr,
PAGE_READWRITE | PAGE_SYSTEM, PAGE_READWRITE | PAGE_SYSTEM,
@ -100,12 +99,12 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
VOID VOID
MmInitKernelMap(PVOID BaseAddress) MmInitKernelMap(PVOID BaseAddress)
{ {
kernel_pool_base = BaseAddress; NonPagedPoolBase = BaseAddress;
KeInitializeSpinLock(&AllocMapLock); KeInitializeSpinLock(&AllocMapLock);
} }
unsigned int PVOID
alloc_pool_region(unsigned int nr_pages) MiAllocNonPagedPoolRegion(ULONG nr_pages)
/* /*
* FUNCTION: Allocates a region of pages within the nonpaged pool area * FUNCTION: Allocates a region of pages within the nonpaged pool area
*/ */
@ -113,12 +112,10 @@ alloc_pool_region(unsigned int nr_pages)
unsigned int start = 0; unsigned int start = 0;
unsigned int length = 0; unsigned int length = 0;
unsigned int i,j; unsigned int i,j;
OLD_DPRINT("alloc_pool_region(nr_pages = %d)\n",nr_pages);
for (i=1; i<ALLOC_MAP_SIZE;i++) for (i=1; i<ALLOC_MAP_SIZE;i++)
{ {
if (!test_bit(i%32,&alloc_map[i/32])) if (!test_bit(i%32,&AllocMap[i/32]))
{ {
if (length == 0) if (length == 0)
{ {
@ -131,15 +128,13 @@ alloc_pool_region(unsigned int nr_pages)
} }
if (length==nr_pages) if (length==nr_pages)
{ {
OLD_DPRINT("found region at %d for %d\n",start,
length);
for (j=start;j<(start+length);j++) for (j=start;j<(start+length);j++)
{ {
set_bit(j%32,&alloc_map[j/32]); set_bit(j%32,&AllocMap[j/32]);
} }
OLD_DPRINT("returning %x\n",(start*PAGESIZE) OLD_DPRINT("returning %x\n",(start*PAGESIZE)
+kernel_pool_base); +kernel_pool_base);
return((ULONG)((start*PAGESIZE)+kernel_pool_base)); return(((start*PAGESIZE)+NonPagedPoolBase));
} }
} }
else else

View file

@ -1,8 +1,8 @@
/* $Id: npool.c,v 1.41 2001/03/14 00:21:22 dwelch Exp $ /* $Id: npool.c,v 1.42 2001/03/14 23:19:14 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pool.c * FILE: ntoskrnl/mm/npool.c
* PURPOSE: Implements the kernel memory pool * PURPOSE: Implements the kernel memory pool
* PROGRAMMER: David Welch (welch@cwcom.net) * PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY: * UPDATE HISTORY:
@ -26,7 +26,19 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
//#define ENABLE_VALIDATE_POOL /* Enable strict checking of the nonpaged pool on every allocation */
/* #define ENABLE_VALIDATE_POOL */
/* Enable tracking of statistics about the tagged blocks in the pool */
#define TAG_STATISTICS_TRACKING
/*
* Put each block in its own range of pages and position the block at the
* end of the range so any accesses beyond the end of block are to invalid
* memory locations.
* FIXME: Not implemented yet.
*/
/* #define WHOLE_PAGE_ALLOCATIONS */
#ifdef ENABLE_VALIDATE_POOL #ifdef ENABLE_VALIDATE_POOL
#define VALIDATE_POOL validate_kernel_pool() #define VALIDATE_POOL validate_kernel_pool()
@ -50,8 +62,8 @@
*/ */
typedef struct _BLOCK_HDR typedef struct _BLOCK_HDR
{ {
ULONG magic; ULONG Magic;
ULONG size; ULONG Size;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
ULONG Tag; ULONG Tag;
PVOID Caller; PVOID Caller;
@ -67,28 +79,59 @@ typedef struct _BLOCK_HDR
static unsigned int kernel_pool_base = 0; static unsigned int kernel_pool_base = 0;
/* /*
* Pointer to the first block in the free list * Head of the list of free blocks
*/ */
static LIST_ENTRY FreeBlockListHead; static LIST_ENTRY FreeBlockListHead;
static LIST_ENTRY UsedBlockListHead;
static ULONG nr_free_blocks;
ULONG EiNrUsedBlocks = 0;
/*
* Head of the list of in use block
*/
static LIST_ENTRY UsedBlockListHead;
/*
* Count of free blocks
*/
static ULONG EiNrFreeBlocks = 0;
/*
* Count of used blocks
*/
static ULONG EiNrUsedBlocks = 0;
/*
* Lock that protects the non-paged pool data structures
*/
static KSPIN_LOCK MmNpoolLock; static KSPIN_LOCK MmNpoolLock;
unsigned int EiFreeNonPagedPool = 0; /*
unsigned int EiUsedNonPagedPool = 0; * Total memory used for free nonpaged pool blocks
*/
ULONG EiFreeNonPagedPool = 0;
unsigned int /*
alloc_pool_region(unsigned int nr_pages); * Total memory used for nonpaged pool blocks
*/
ULONG EiUsedNonPagedPool = 0;
/*
* Allocate a range of memory in the nonpaged pool
*/
PVOID
MiAllocNonPagedPoolRegion(unsigned int nr_pages);
#ifdef TAG_STATISTICS_TRACKING
#define TAG_HASH_TABLE_SIZE (1024) #define TAG_HASH_TABLE_SIZE (1024)
static BLOCK_HDR* tag_hash_table[TAG_HASH_TABLE_SIZE]; static BLOCK_HDR* tag_hash_table[TAG_HASH_TABLE_SIZE];
#endif /* TAG_STATISTICS_TRACKING */
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
#ifdef TAG_STATISTICS_TRACKING
VOID VOID
MiRemoveFromTagHashTable(BLOCK_HDR* block) MiRemoveFromTagHashTable(BLOCK_HDR* block)
/*
* Remove a block from the tag hash table
*/
{ {
BLOCK_HDR* previous; BLOCK_HDR* previous;
BLOCK_HDR* current; BLOCK_HDR* current;
@ -127,6 +170,9 @@ MiRemoveFromTagHashTable(BLOCK_HDR* block)
VOID VOID
MiAddToTagHashTable(BLOCK_HDR* block) MiAddToTagHashTable(BLOCK_HDR* block)
/*
* Add a block to the tag hash table
*/
{ {
ULONG hash; ULONG hash;
BLOCK_HDR* current; BLOCK_HDR* current;
@ -162,6 +208,7 @@ MiAddToTagHashTable(BLOCK_HDR* block)
previous->tag_next = block; previous->tag_next = block;
} }
} }
#endif /* TAG_STATISTICS_TRACKING */
VOID VOID
ExInitNonPagedPool(ULONG BaseAddress) ExInitNonPagedPool(ULONG BaseAddress)
@ -174,6 +221,7 @@ ExInitNonPagedPool(ULONG BaseAddress)
InitializeListHead(&UsedBlockListHead); InitializeListHead(&UsedBlockListHead);
} }
#ifdef TAG_STATISTICS_TRACKING
VOID STATIC VOID STATIC
MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize) MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize)
{ {
@ -197,10 +245,12 @@ MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize)
CurrentSize / CurrentNrBlocks); CurrentSize / CurrentNrBlocks);
} }
} }
#endif /* TAG_STATISTICS_TRACKING */
VOID VOID
MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly) MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
{ {
#ifdef TAG_STATISTICS_TRACKING
ULONG i; ULONG i;
BLOCK_HDR* current; BLOCK_HDR* current;
ULONG CurrentTag; ULONG CurrentTag;
@ -235,8 +285,8 @@ MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
{ {
CurrentNrBlocks++; CurrentNrBlocks++;
TotalBlocks++; TotalBlocks++;
CurrentSize = CurrentSize + current->size; CurrentSize = CurrentSize + current->Size;
TotalSize = TotalSize + current->size; TotalSize = TotalSize + current->Size;
current->Dumped = TRUE; current->Dumped = TRUE;
} }
current = current->tag_next; current = current->tag_next;
@ -257,6 +307,7 @@ MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
TotalBlocks, TotalSize); TotalBlocks, TotalSize);
} }
DbgPrint("***************** Dump Complete ***************\n"); DbgPrint("***************** Dump Complete ***************\n");
#endif /* TAG_STATISTICS_TRACKING */
} }
VOID VOID
@ -285,13 +336,13 @@ MiDebugDumpNonPagedPool(BOOLEAN NewOnly)
if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4))
{ {
DbgPrint("Size 0x%x Tag 0x%x (%c%c%c%c) Allocator 0x%x\n", DbgPrint("Size 0x%x Tag 0x%x (%c%c%c%c) Allocator 0x%x\n",
current->size, current->Tag, c4, c3, c2, c1, current->Size, current->Tag, c4, c3, c2, c1,
current->Caller); current->Caller);
} }
else else
{ {
DbgPrint("Size 0x%x Tag 0x%x Allocator 0x%x\n", DbgPrint("Size 0x%x Tag 0x%x Allocator 0x%x\n",
current->size, current->Tag, current->Caller); current->Size, current->Tag, current->Caller);
} }
current->Dumped = TRUE; current->Dumped = TRUE;
} }
@ -319,7 +370,7 @@ static void validate_free_list(void)
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry); current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
base_addr = (int)current; base_addr = (int)current;
if (current->magic != BLOCK_HDR_FREE_MAGIC) if (current->Magic != BLOCK_HDR_FREE_MAGIC)
{ {
DbgPrint("Bad block magic (probable pool corruption) at %x\n", DbgPrint("Bad block magic (probable pool corruption) at %x\n",
current); current);
@ -327,19 +378,18 @@ static void validate_free_list(void)
} }
if (base_addr < (kernel_pool_base) || if (base_addr < (kernel_pool_base) ||
(base_addr+current->size) > (base_addr+current->Size) > (kernel_pool_base)+NONPAGED_POOL_SIZE)
(kernel_pool_base)+NONPAGED_POOL_SIZE)
{ {
DbgPrint("Block %x found outside pool area\n",current); DbgPrint("Block %x found outside pool area\n",current);
DbgPrint("Size %d\n",current->size); DbgPrint("Size %d\n",current->Size);
DbgPrint("Limits are %x %x\n",kernel_pool_base, DbgPrint("Limits are %x %x\n",kernel_pool_base,
kernel_pool_base+NONPAGED_POOL_SIZE); kernel_pool_base+NONPAGED_POOL_SIZE);
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
} }
blocks_seen++; blocks_seen++;
if (blocks_seen > nr_free_blocks) if (blocks_seen > EiNrFreeBlocks)
{ {
DbgPrint("Too many blocks on list\n"); DbgPrint("Too many blocks on free list\n");
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
} }
if (current->ListEntry.Flink != &FreeBlockListHead && if (current->ListEntry.Flink != &FreeBlockListHead &&
@ -373,7 +423,7 @@ static void validate_used_list(void)
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry); current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
base_addr = (int)current; base_addr = (int)current;
if (current->magic != BLOCK_HDR_USED_MAGIC) if (current->Magic != BLOCK_HDR_USED_MAGIC)
{ {
DbgPrint("Bad block magic (probable pool corruption) at %x\n", DbgPrint("Bad block magic (probable pool corruption) at %x\n",
current); current);
@ -389,7 +439,7 @@ static void validate_used_list(void)
blocks_seen++; blocks_seen++;
if (blocks_seen > EiNrUsedBlocks) if (blocks_seen > EiNrUsedBlocks)
{ {
DbgPrint("Too many blocks on list\n"); DbgPrint("Too many blocks on used list\n");
for(;;); for(;;);
} }
if (current->ListEntry.Flink != &UsedBlockListHead && if (current->ListEntry.Flink != &UsedBlockListHead &&
@ -422,7 +472,7 @@ static void check_duplicates(BLOCK_HDR* blk)
{ {
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry); current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
if (current->magic != BLOCK_HDR_FREE_MAGIC) if (current->Magic != BLOCK_HDR_FREE_MAGIC)
{ {
DbgPrint("Bad block magic (probable pool corruption) at %x\n", DbgPrint("Bad block magic (probable pool corruption) at %x\n",
current); current);
@ -500,15 +550,23 @@ static void validate_kernel_pool(void)
STATIC VOID STATIC VOID
free_pages(BLOCK_HDR* blk) free_pages(BLOCK_HDR* blk)
{ {
if (PAGE_ROUND_UP(((unsigned int)blk)) != ULONG start;
PAGE_ROUND_DOWN(((unsigned int)blk + blk->size))) ULONG end;
ULONG i;
start = (ULONG)blk;
end = (ULONG)blk + sizeof(BLOCK_HDR) + blk->Size;
/*
* If the block doesn't contain a whole page then there is nothing to do
*/
if (PAGE_ROUND_UP(start) >= PAGE_ROUND_DOWN(end))
{ {
return;
} }
} }
#endif #endif
#if 0
STATIC VOID STATIC VOID
merge_free_block(BLOCK_HDR* blk) merge_free_block(BLOCK_HDR* blk)
{ {
@ -521,10 +579,12 @@ merge_free_block(BLOCK_HDR* blk)
if (next_entry != &FreeBlockListHead) if (next_entry != &FreeBlockListHead)
{ {
next = CONTAINING_RECORD(next_entry, BLOCK_HDR, ListEntry); next = CONTAINING_RECORD(next_entry, BLOCK_HDR, ListEntry);
if (((unsigned int)blk + blk->size) == (unsigned int)next) if (((unsigned int)blk + sizeof(BLOCK_HDR) + blk->Size) ==
(unsigned int)next)
{ {
RemoveEntryList(&next->ListEntry); RemoveEntryList(&next->ListEntry);
blk->size = blk->size + sizeof(BLOCK_HDR) + next->size; blk->Size = blk->Size + sizeof(BLOCK_HDR) + next->Size;
EiNrFreeBlocks--;
} }
} }
@ -532,14 +592,15 @@ merge_free_block(BLOCK_HDR* blk)
if (previous_entry != &FreeBlockListHead) if (previous_entry != &FreeBlockListHead)
{ {
previous = CONTAINING_RECORD(previous_entry, BLOCK_HDR, ListEntry); previous = CONTAINING_RECORD(previous_entry, BLOCK_HDR, ListEntry);
if (((unsigned int)previous + previous->size) == (unsigned int)blk) if (((unsigned int)previous + sizeof(BLOCK_HDR) + previous->Size) ==
(unsigned int)blk)
{ {
RemoveEntryList(&blk->ListEntry); RemoveEntryList(&blk->ListEntry);
previous->size = previous->size + sizeof(BLOCK_HDR) + blk->size; previous->Size = previous->Size + sizeof(BLOCK_HDR) + blk->Size;
EiNrFreeBlocks--;
} }
} }
} }
#endif
STATIC VOID STATIC VOID
add_to_free_list(BLOCK_HDR* blk) add_to_free_list(BLOCK_HDR* blk)
@ -547,36 +608,28 @@ add_to_free_list(BLOCK_HDR* blk)
* FUNCTION: add the block to the free list (internal) * FUNCTION: add the block to the free list (internal)
*/ */
{ {
#if 1
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PLIST_ENTRY next_entry;
BLOCK_HDR* current; BLOCK_HDR* current;
BLOCK_HDR* next;
current_entry = FreeBlockListHead.Flink; current_entry = FreeBlockListHead.Flink;
next_entry = FreeBlockListHead.Flink->Flink; while (current_entry != &FreeBlockListHead)
while (current_entry != &FreeBlockListHead &&
next_entry != &FreeBlockListHead)
{ {
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry); current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
next = CONTAINING_RECORD(next_entry, BLOCK_HDR, ListEntry);
if ((unsigned int)current < (unsigned int)blk && if ((unsigned int)current > (unsigned int)blk)
(unsigned int)next > (unsigned int)blk)
{ {
InsertHeadList(current_entry, &blk->ListEntry); blk->ListEntry.Flink = current_entry;
blk->ListEntry.Blink = current_entry->Blink;
current_entry->Blink->Flink = &blk->ListEntry;
current_entry->Blink = &blk->ListEntry;
EiNrFreeBlocks++;
return; return;
} }
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
next_entry = next_entry->Flink;
} }
InsertTailList(&FreeBlockListHead, &blk->ListEntry); InsertTailList(&FreeBlockListHead, &blk->ListEntry);
nr_free_blocks++; EiNrFreeBlocks++;
#else
InsertHeadList(&FreeBlockListHead, &blk->ListEntry);
nr_free_blocks++;
#endif
} }
static void add_to_used_list(BLOCK_HDR* blk) static void add_to_used_list(BLOCK_HDR* blk)
@ -592,7 +645,7 @@ static void add_to_used_list(BLOCK_HDR* blk)
static void remove_from_free_list(BLOCK_HDR* current) static void remove_from_free_list(BLOCK_HDR* current)
{ {
RemoveEntryList(&current->ListEntry); RemoveEntryList(&current->ListEntry);
nr_free_blocks--; EiNrFreeBlocks--;
} }
@ -626,7 +679,7 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
{ {
unsigned int total_size = size + sizeof(BLOCK_HDR); unsigned int total_size = size + sizeof(BLOCK_HDR);
unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGESIZE; unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGESIZE;
unsigned int start = alloc_pool_region(nr_pages); unsigned int start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages);
BLOCK_HDR* used_blk=NULL; BLOCK_HDR* used_blk=NULL;
BLOCK_HDR* free_blk=NULL; BLOCK_HDR* free_blk=NULL;
int i; int i;
@ -653,33 +706,35 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
{ {
used_blk = (struct _BLOCK_HDR *)start; used_blk = (struct _BLOCK_HDR *)start;
OLD_DPRINT("Creating block at %x\n",start); OLD_DPRINT("Creating block at %x\n",start);
used_blk->magic = BLOCK_HDR_USED_MAGIC; used_blk->Magic = BLOCK_HDR_USED_MAGIC;
used_blk->size = size; used_blk->Size = size;
add_to_used_list(used_blk); add_to_used_list(used_blk);
free_blk = (BLOCK_HDR *)(start + sizeof(BLOCK_HDR) + size); free_blk = (BLOCK_HDR *)(start + sizeof(BLOCK_HDR) + size);
OLD_DPRINT("Creating block at %x\n",free_blk); OLD_DPRINT("Creating block at %x\n",free_blk);
free_blk->magic = BLOCK_HDR_FREE_MAGIC; free_blk->Magic = BLOCK_HDR_FREE_MAGIC;
free_blk->size = (nr_pages * PAGESIZE) -((sizeof(BLOCK_HDR)*2) + size); free_blk->Size = (nr_pages * PAGESIZE) -((sizeof(BLOCK_HDR)*2) + size);
add_to_free_list(free_blk); add_to_free_list(free_blk);
EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size; EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->Size;
EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size; EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->Size;
} }
else else
{ {
used_blk = (struct _BLOCK_HDR *)start; used_blk = (struct _BLOCK_HDR *)start;
used_blk->magic = BLOCK_HDR_USED_MAGIC; used_blk->Magic = BLOCK_HDR_USED_MAGIC;
used_blk->size = (nr_pages * PAGESIZE) - sizeof(BLOCK_HDR); used_blk->Size = (nr_pages * PAGESIZE) - sizeof(BLOCK_HDR);
add_to_used_list(used_blk); add_to_used_list(used_blk);
EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size; EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->Size;
} }
used_blk->Tag = Tag; used_blk->Tag = Tag;
used_blk->Caller = Caller; used_blk->Caller = Caller;
used_blk->Dumped = FALSE; used_blk->Dumped = FALSE;
#ifdef TAG_STATISTICS_TRACKING
MiAddToTagHashTable(used_blk); MiAddToTagHashTable(used_blk);
#endif /* TAG_STATISTICS_TRACKING */
VALIDATE_POOL; VALIDATE_POOL;
return(used_blk); return(used_blk);
@ -699,11 +754,11 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
* between the sizes is marginal it makes no sense to have the * between the sizes is marginal it makes no sense to have the
* extra overhead * extra overhead
*/ */
if (current->size > (1 + size + sizeof(BLOCK_HDR))) if (current->Size > (1 + size + sizeof(BLOCK_HDR)))
{ {
BLOCK_HDR* free_blk; BLOCK_HDR* free_blk;
EiFreeNonPagedPool = EiFreeNonPagedPool - current->size; EiFreeNonPagedPool = EiFreeNonPagedPool - current->Size;
/* /*
* Replace the bigger block with a smaller block in the * Replace the bigger block with a smaller block in the
@ -711,22 +766,24 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
*/ */
free_blk = (BLOCK_HDR *)(((int)current) free_blk = (BLOCK_HDR *)(((int)current)
+ sizeof(BLOCK_HDR) + size); + sizeof(BLOCK_HDR) + size);
free_blk->magic = BLOCK_HDR_FREE_MAGIC; free_blk->Magic = BLOCK_HDR_FREE_MAGIC;
InsertHeadList(&current->ListEntry, &free_blk->ListEntry); InsertHeadList(&current->ListEntry, &free_blk->ListEntry);
free_blk->size = current->size - (sizeof(BLOCK_HDR) + size); free_blk->Size = current->Size - (sizeof(BLOCK_HDR) + size);
current->size=size; current->Size=size;
RemoveEntryList(&current->ListEntry); RemoveEntryList(&current->ListEntry);
InsertHeadList(&UsedBlockListHead, &current->ListEntry); InsertHeadList(&UsedBlockListHead, &current->ListEntry);
EiNrUsedBlocks++; EiNrUsedBlocks++;
current->magic = BLOCK_HDR_USED_MAGIC; current->Magic = BLOCK_HDR_USED_MAGIC;
current->Tag = Tag; current->Tag = Tag;
current->Caller = Caller; current->Caller = Caller;
current->Dumped = FALSE; current->Dumped = FALSE;
#ifdef TAG_STATISTICS_TRACKING
MiAddToTagHashTable(current); MiAddToTagHashTable(current);
#endif /* TAG_STATISTICS_TRACKING */
EiUsedNonPagedPool = EiUsedNonPagedPool + current->size; EiUsedNonPagedPool = EiUsedNonPagedPool + current->Size;
EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size; EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->Size;
VALIDATE_POOL; VALIDATE_POOL;
return(block_to_address(current)); return(block_to_address(current));
@ -738,14 +795,16 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
remove_from_free_list(current); remove_from_free_list(current);
add_to_used_list(current); add_to_used_list(current);
EiFreeNonPagedPool = EiFreeNonPagedPool - current->size; EiFreeNonPagedPool = EiFreeNonPagedPool - current->Size;
EiUsedNonPagedPool = EiUsedNonPagedPool + current->size; EiUsedNonPagedPool = EiUsedNonPagedPool + current->Size;
current->magic = BLOCK_HDR_USED_MAGIC; current->Magic = BLOCK_HDR_USED_MAGIC;
current->Tag = Tag; current->Tag = Tag;
current->Caller = Caller; current->Caller = Caller;
current->Dumped = FALSE; current->Dumped = FALSE;
#ifdef TAG_STATISTICS_TRACKING
MiAddToTagHashTable(current); MiAddToTagHashTable(current);
#endif /* TAG_STATISTICS_TRACKING */
VALIDATE_POOL; VALIDATE_POOL;
return(block_to_address(current)); return(block_to_address(current));
@ -770,33 +829,33 @@ VOID STDCALL ExFreePool (PVOID block)
VALIDATE_POOL; VALIDATE_POOL;
if (blk->magic != BLOCK_HDR_USED_MAGIC) if (blk->Magic != BLOCK_HDR_USED_MAGIC)
{ {
if (blk->magic == BLOCK_HDR_FREE_MAGIC) if (blk->Magic == BLOCK_HDR_FREE_MAGIC)
{ {
DbgPrint("ExFreePool of already freed address %x\n", block); DbgPrint("ExFreePool of already freed address %x\n", block);
} }
else else
{ {
DbgPrint("ExFreePool of non-allocated address %x (magic %x)\n", DbgPrint("ExFreePool of non-allocated address %x (magic %x)\n",
block, blk->magic); block, blk->Magic);
} }
KeBugCheck(0); KeBugCheck(0);
return; return;
} }
memset(block, 0xcc, blk->size); memset(block, 0xcc, blk->Size);
/* #ifdef TAG_STATISTICS_TRACKING
* Please don't change the order
*/
MiRemoveFromTagHashTable(blk); MiRemoveFromTagHashTable(blk);
#endif /* TAG_STATISTICS_TRACKING */
remove_from_used_list(blk); remove_from_used_list(blk);
blk->Magic = BLOCK_HDR_FREE_MAGIC;
add_to_free_list(blk); add_to_free_list(blk);
blk->magic = BLOCK_HDR_FREE_MAGIC; merge_free_block(blk);
EiUsedNonPagedPool = EiUsedNonPagedPool - blk->size; EiUsedNonPagedPool = EiUsedNonPagedPool - blk->Size;
EiFreeNonPagedPool = EiFreeNonPagedPool + blk->size; EiFreeNonPagedPool = EiFreeNonPagedPool + blk->Size;
VALIDATE_POOL; VALIDATE_POOL;
@ -838,8 +897,8 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
OLD_DPRINT("current %x size %x next %x\n",current,current->size, OLD_DPRINT("current %x size %x next %x\n",current,current->size,
current->next); current->next);
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry); current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
if (current->size >= Size && if (current->Size >= Size &&
(best == NULL || current->size < best->size)) (best == NULL || current->Size < best->Size))
{ {
best = current; best = current;
} }
@ -847,11 +906,9 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
} }
if (best != NULL) if (best != NULL)
{ {
OLD_DPRINT("found block %x of size %d\n",best,size);
block=take_block(best, Size, Tag, Caller); block=take_block(best, Size, Tag, Caller);
VALIDATE_POOL; VALIDATE_POOL;
memset(block,0,Size); memset(block,0,Size);
POOL_TRACE("= %x\n",block);
KeReleaseSpinLock(&MmNpoolLock, oldIrql); KeReleaseSpinLock(&MmNpoolLock, oldIrql);
return(block); return(block);
} }
@ -862,8 +919,7 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller)
*/ */
block=block_to_address(grow_kernel_pool(Size, Tag, Caller)); block=block_to_address(grow_kernel_pool(Size, Tag, Caller));
VALIDATE_POOL; VALIDATE_POOL;
memset(block,0,Size); memset(block, 0, Size);
POOL_TRACE("= %x\n",block);
KeReleaseSpinLock(&MmNpoolLock, oldIrql); KeReleaseSpinLock(&MmNpoolLock, oldIrql);
return(block); return(block);
} }