3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/ppool.c
6 * PURPOSE: Implements the paged pool
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
14 #ifdef PPOOL_UMODE_TEST
15 #include "ppool_umode.h"
16 #else//PPOOL_UMODE_TEST
19 #include <internal/debug.h>
20 #endif//PPOOL_UMODE_TEST
23 #define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
27 #define R_MUTEX FAST_MUTEX
28 #define R_ACQUIRE_MUTEX(pool) /*DPRINT1("Acquiring PPool Mutex\n");*/ ExAcquireFastMutex(&pool->Mutex)
29 #define R_RELEASE_MUTEX(pool) /*DPRINT1("Releasing PPool Mutex\n");*/ ExReleaseFastMutex(&pool->Mutex)
30 #define R_PRINT_ADDRESS(addr) KeRosPrintAddress(addr)
31 #define R_PANIC() KeBugCheck(0)
32 #define R_DEBUG DbgPrint
33 #define R_EXTRA_STACK_UP 2
34 #define R_GET_STACK_FRAMES(ptr,cnt) KeRosGetStackFrames(ptr,cnt)
38 /* GLOBALS *******************************************************************/
40 PVOID MmPagedPoolBase
;
41 ULONG MmPagedPoolSize
;
42 ULONG MmTotalPagedPoolQuota
= 0; // TODO FIXME commented out until we use it
43 static PR_POOL MmPagedPool
= NULL
;
45 /* FUNCTIONS *****************************************************************/
48 MmInitializePagedPool()
51 * We are still at a high IRQL level at this point so explicitly commit
52 * the first page of the paged pool before writing the first block header.
54 MmCommitPagedPoolAddress ( (PVOID
)MmPagedPoolBase
, FALSE
);
56 MmPagedPool
= RPoolInit ( MmPagedPoolBase
,
62 ExInitializeFastMutex(&MmPagedPool
->Mutex
);
65 /**********************************************************************
67 * ExAllocatePagedPoolWithTag@12
76 ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType
,
77 IN ULONG NumberOfBytes
,
82 if ( NumberOfBytes
>= PAGE_SIZE
)
84 else if ( PoolType
== PagedPoolCacheAligned
)
89 ASSERT_IRQL(APC_LEVEL
);
91 return RPoolAlloc ( MmPagedPool
, NumberOfBytes
, Tag
, align
);
95 ExFreePagedPool(IN PVOID Block
)
97 ASSERT_IRQL(APC_LEVEL
);
98 RPoolFree ( MmPagedPool
, Block
);
102 ExRosDumpPagedPoolByTag ( ULONG Tag
)
104 // TODO FIXME - should we ASSERT_IRQL?
105 RPoolDumpByTag ( MmPagedPool
, Tag
);
109 ExRosQueryPagedPoolTag ( PVOID Addr
)
111 // TODO FIXME - should we ASSERT_IRQL?
112 return RPoolQueryTag ( Addr
);
115 #ifdef PPOOL_UMODE_TEST
117 PVOID
TestAlloc ( ULONG Bytes
)
121 //printf ( "Allocating block: " ); RPoolStats ( MmPagedPool );
122 //RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
124 ret
= ExAllocatePagedPoolWithTag ( PagedPool
, Bytes
, 0 );
126 //printf ( "Block %x allocated: ", ret ); RPoolStats ( MmPagedPool );
127 //RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
132 void TestFree ( PVOID ptr
)
134 //printf ( "Freeing block %x: ", ptr ); RPoolStats ( MmPagedPool );
135 //RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
136 ExFreePagedPool(ptr
);
137 //printf ( "Block %x freed: ", ptr ); RPoolStats ( MmPagedPool );
138 //RPoolRedZoneCheck ( MmPagedPool, __FILE__, __LINE__ );
145 char* keepers
[COUNT
];
147 int AllocSize
[] = { 15, 31, 63, 127, 255, 511, 1023, 2047 };
148 const int ALLOCS
= sizeof(AllocSize
) / sizeof(0[AllocSize
]);
151 MmPagedPoolSize
= 1*1024*1024;
152 MmPagedPoolBase
= malloc ( MmPagedPoolSize
);
153 MmInitializePagedPool();
155 dwStart
= GetTickCount();
157 printf ( "test #1 phase #1\n" );
158 for ( i
= 0; i
< COUNT
; i
++ )
160 //printf ( "keeper %i) ", i );
161 keepers
[i
] = TestAlloc ( AllocSize
[i
%ALLOCS
] );
162 if ( !keepers
[i
] ) printf ( "allocation failed\n" );
163 //printf ( "trash %i) ", i );
164 trash
[i
] = TestAlloc ( AllocSize
[i
%ALLOCS
] );
165 if ( !trash
[i
] ) printf ( "allocation failed\n" );
168 printf ( "test #1 phase #2\n" );
169 for ( i
= 0; i
< COUNT
; i
++ )
173 //printf ( "%i) ", i );
174 TestFree ( trash
[i
] );
177 printf ( "test #1 phase #3\n" );
178 for ( i
= 0; i
< 4; i
++ )
180 //printf ( "%i) ", i );
181 keepers
[i
] = TestAlloc ( 4096 );
182 if ( !keepers
[i
] ) printf ( "allocation failed\n" );
185 printf ( "test #1 phase #4\n" );
186 for ( i
= 0; i
< 4; i
++ )
188 //printf ( "%i) ", i );
189 TestFree ( keepers
[i
] );
192 printf ( "test #1 phase #5\n" );
194 for ( i
= 0; i
< COUNT
; i
++ )
196 //printf ( "%i) ", i );
197 trash
[i
] = TestAlloc ( rand()%1024+1 );
198 if ( !trash
[i
] ) printf ( "allocation failed\n" );
200 printf ( "test #1 phase #6\n" );
201 for ( i
= 0; i
< 10000; i
++ )
203 TestFree ( trash
[i
%COUNT
] );
204 trash
[i
%COUNT
] = TestAlloc ( rand()%1024+1 );
205 if ( !trash
[i
%COUNT
] ) printf ( "allocation failed\n" );
207 printf ( "test #1 phase #7\n" );
209 for ( i
= 0; i
< COUNT
; i
++ )
213 TestFree ( trash
[i
] );
217 printf ( "test #1 phase #8 ( freed %i of %i trash )\n", j
, COUNT
);
218 if ( !TestAlloc ( 2048 ) )
219 printf ( "Couldn't allocate 2048 bytes after freeing up a whole bunch of blocks\n" );
221 free ( MmPagedPoolBase
);
223 printf ( "test time: %lu\n", GetTickCount() - dwStart
);
225 printf ( "test #2\n" );
227 MmPagedPoolSize
= 1024;
228 MmPagedPoolBase
= malloc ( MmPagedPoolSize
);
229 MmInitializePagedPool();
232 i
= RPoolLargestAllocPossible ( MmPagedPool
, 0 );
233 if ( !TestAlloc ( i
) )
235 printf ( "allocating last available block failed\n" );
238 free ( MmPagedPoolBase
);
240 printf ( "done!\n" );
243 #endif//PPOOL_UMODE_TEST