#include <memblk.h>
Public Member Functions | |
MemoryBlock () | |
Some items start small and get large. The MemoryBlock class encapsulates memory management for objects that generally need to be fixed in memory but need to grow, and are generally large. Items that use the class include the handles table and the relocatable heap.Constructor. Initialises some fields to zero. Does not do any allocations. | |
~MemoryBlock () | |
Destructor. Doesn't do anything really, though might do a DeInit one day. | |
LPVOID | Init (INT32 InitSize, BOOL AutoZero, MemoryBlockType) |
Sets up block for subsequent allocations. | |
void | DeInit () |
Frees up any allocations on this memory block. Should always be called during exit for a tidy cleanup. | |
BOOL | Grow (UINT32 OldSize, UINT32 NewSize, LPVOID *Pointer) |
Like GlobalReAlloc in a way, but a safer version that does all it can to ensure existing data doesn't get thrown away. Handles unlocking, reallocing and relocking the result. Even if the return value is FALSE, the data might still have been moved - see if *Pointer has changed if this is important to you. | |
BOOL | Shrink (UINT32 OldSize, UINT32 NewSize, LPVOID *Pointer) |
Reduces the current allocation, without throwing away data. Normally this should always work, as giving memory back shouldn't ever fail, but a FALSE return means we couldn't. If a FALSE return is combined with a NULL Pointer return, it means an extremely bad thing occurred and the original data has been lost. | |
UINT32 | GetRoundedSize (UINT32 RawSize) |
Private Attributes | |
UINT32 | m_RoundedSize |
PVOID | m_pMemBlk |
Definition at line 123 of file memblk.h.
|
Some items start small and get large. The MemoryBlock class encapsulates memory management for objects that generally need to be fixed in memory but need to grow, and are generally large. Items that use the class include the handles table and the relocatable heap.Constructor. Initialises some fields to zero. Does not do any allocations.
Definition at line 148 of file memblk.cpp. 00149 { 00150 #if USE_STD_ALLOC 00151 #elif USE_VM_BLOCKS 00152 MemBase = NULL; 00153 #else 00154 MemHandle = 0; 00155 #endif 00156 }
|
|
Destructor. Doesn't do anything really, though might do a DeInit one day.
Definition at line 171 of file memblk.cpp.
|
|
Frees up any allocations on this memory block. Should always be called during exit for a tidy cleanup.
Definition at line 317 of file memblk.cpp. 00318 { 00319 #if USE_STD_ALLOC 00320 if( NULL != m_pMemBlk ) 00321 { 00322 CCFree( m_pMemBlk ); 00323 m_pMemBlk = NULL; 00324 } 00325 #elif USE_VM_BLOCKS 00326 if (MemBase) 00327 { 00328 BOOL Result = VirtualFree(MemBase, 0L, MEM_RELEASE); 00329 MemBase = NULL; 00330 ENSURE( Result, "VirtualFree failed"); 00331 } 00332 #else 00333 if (MemHandle) 00334 { 00335 GlobalUnlock( MemHandle ); 00336 GlobalFree( MemHandle ); 00337 MemHandle = 0; 00338 } 00339 #endif 00340 }
|
|
Definition at line 137 of file memblk.h.
|
|
Like GlobalReAlloc in a way, but a safer version that does all it can to ensure existing data doesn't get thrown away. Handles unlocking, reallocing and relocking the result. Even if the return value is FALSE, the data might still have been moved - see if *Pointer has changed if this is important to you.
Definition at line 454 of file memblk.cpp. 00455 { 00456 #if USE_STD_ALLOC 00457 NewSize = GetRoundedSize( NewSize ); // round new size up 00458 if( NewSize == m_RoundedSize ) 00459 return TRUE; // if same physical size 00460 00461 LPVOID NewPtr = CCRealloc( *Pointer, NewSize ); 00462 if (NewPtr==NULL) 00463 { 00464 TRACEUSER( "Andy", wxT("CCRealloc growing from %ld to %ld failed\n"), OldSize, NewSize); 00465 return FALSE; 00466 } 00467 *Pointer = m_pMemBlk = NewPtr; 00468 m_RoundedSize = NewSize; 00469 return TRUE; 00470 00471 #elif USE_VM_BLOCKS 00472 NewSize = GetRoundedSize( NewSize ); // round new size up 00473 if (NewSize == RoundedSize) 00474 return TRUE; // if same physical size 00475 00476 LPVOID NewPtr = VirtualAlloc( MemBase, NewSize, MEM_COMMIT, PAGE_READWRITE ); 00477 if (NewPtr==NULL) 00478 { 00479 TRACEUSER( "Andy", wxT("VirtualAlloc growing from %ld to %ld failed\n"), OldSize, NewSize); 00480 return FALSE; 00481 } 00482 *Pointer = NewPtr; 00483 RoundedSize = NewSize; 00484 return TRUE; 00485 00486 #else 00487 const UINT32 Flags = AutoZero ? GMEM_ZEROINIT : 0; 00488 00489 #ifndef WIN32 00490 if (NewSize > MAX_BLOCK) 00491 return FALSE; 00492 #endif 00493 00494 return DoGrowGlobalHandle( &MemHandle, OldSize, NewSize, Flags, Pointer ); 00495 #endif 00496 }
|
|
Sets up block for subsequent allocations.
Definition at line 190 of file memblk.cpp. 00191 { 00192 #if USE_STD_ALLOC 00193 00194 m_RoundedSize = GetRoundedSize( InitSize ); 00195 00196 // now physically grab the starting size 00197 LPVOID pNewPtr; 00198 if( bAutoZero ) 00199 { 00200 pNewPtr = CCMalloc( m_RoundedSize ); 00201 memset(pNewPtr, 0, m_RoundedSize); 00202 } 00203 else 00204 { 00205 pNewPtr = CCMalloc( m_RoundedSize ); 00206 } 00207 00208 if( pNewPtr == NULL ) 00209 { 00210 TRACEUSER( "Andy", wxT("malloc() failed because %lx\n"), errno ); 00211 return NULL; 00212 } 00213 00214 TRACEUSER( "Andy", wxT("malloc OK at %p\n"), pNewPtr ); 00215 m_pMemBlk = pNewPtr; 00216 return pNewPtr; 00217 00218 #elif USE_VM_BLOCKS 00219 00220 // first time we are called get the page size 00221 if (PageSize==0L) 00222 { 00223 SYSTEM_INFO SysInfo; 00224 GetSystemInfo( &SysInfo ); 00225 PageSize = SysInfo.dwPageSize; 00226 } 00227 00228 // Note that the Virtual API always gives us zeroed memory whether we want it or not 00229 00230 00231 // calculate a suitable maximum size for the type of block 00232 INT32 LargestSize; 00233 00234 switch (Type) 00235 { 00236 case MEMORYBLOCK_HANDLETABLE: 00237 LargestSize = 0x01000000; // 16M of handles is enough 00238 break; 00239 case MEMORYBLOCK_RELOCHEAP: 00240 LargestSize = 0x10000000; // 256M of reloc heap 00241 break; 00242 case MEMORYBLOCK_SCREENBUFFER: 00243 LargestSize = 0x01000000; // 1024x768x32bits x4 for good measure 00244 break; 00245 default: 00246 ENSURE( FALSE, "Bad type in MemoryBlock::Init"); 00247 return NULL; 00248 } 00249 00250 // firstly reserve a gratuitously large chunk of address space 00251 00252 MemBase = VirtualAlloc( NULL, LargestSize, MEM_RESERVE, PAGE_NOACCESS ); 00253 if (MemBase==NULL) 00254 { 00255 TRACEUSER( "Andy", wxT("VirtualAlloc(reserve) failed because %lx\n"), GetLastError() ); 00256 return NULL; 00257 } 00258 00259 RoundedSize = GetRoundedSize( InitSize ); 00260 00261 // now physically grab the starting size 00262 LPVOID NewPtr = VirtualAlloc( MemBase, RoundedSize, MEM_COMMIT, PAGE_READWRITE ); 00263 if (NewPtr==NULL) 00264 { 00265 TRACEUSER( "Andy", wxT("VirtualAlloc(commit) failed because %lx\n"), GetLastError() ); 00266 VirtualFree(MemBase, 0L, MEM_RELEASE ); 00267 MemBase = NULL; 00268 return NULL; 00269 } 00270 00271 TRACEUSER( "Andy", wxT("VirtualAlloced OK at %lx from %lx\n"), NewPtr, MemBase ); 00272 00273 return NewPtr; 00274 #else 00275 00276 #ifndef WIN32 00277 if (InitSize > MAX_BLOCK) 00278 return NULL; 00279 #endif 00280 00281 AutoZero = bAutoZero; // remember flag in struct 00282 00283 UINT32 Flags = GMEM_MOVEABLE; 00284 if (AutoZero) 00285 Flags |= GMEM_ZEROINIT; 00286 00287 MemHandle = GlobalAlloc( Flags, InitSize ); 00288 TRACE( wxT("GlobalAlloc %u %lx returned %x\n"), Flags, InitSize, (INT32)MemHandle); 00289 if (MemHandle==NULL) 00290 return NULL; 00291 00292 LPVOID Ptr = GlobalLock( MemHandle ); 00293 if (Ptr == NULL) 00294 { 00295 GlobalFree( MemHandle ); 00296 MemHandle = 0; 00297 return NULL; 00298 } 00299 00300 return Ptr; 00301 #endif 00302 }
|
|
Reduces the current allocation, without throwing away data. Normally this should always work, as giving memory back shouldn't ever fail, but a FALSE return means we couldn't. If a FALSE return is combined with a NULL Pointer return, it means an extremely bad thing occurred and the original data has been lost.
Definition at line 517 of file memblk.cpp. 00518 { 00519 #if USE_STD_ALLOC 00520 00521 OldSize = GetRoundedSize( OldSize ); 00522 NewSize = GetRoundedSize( NewSize ); 00523 00524 if (OldSize == NewSize) 00525 return TRUE; // no change required 00526 00527 if (OldSize < NewSize) 00528 { 00529 ENSURE(FALSE, "Cannot Shrink backwards"); 00530 return FALSE; 00531 } // if same physical size 00532 00533 LPVOID NewPtr = CCRealloc( *Pointer, NewSize ); 00534 if (NewPtr==NULL) 00535 { 00536 TRACEUSER( "Andy", wxT("CCRealloc growing from %ld to %ld failed\n"), OldSize, NewSize); 00537 return FALSE; 00538 } 00539 *Pointer = m_pMemBlk = NewPtr; 00540 m_RoundedSize = NewSize; 00541 return TRUE; 00542 00543 #elif USE_VM_BLOCKS 00544 00545 // we do a shrink by freeing up spare blocks 00546 00547 OldSize = GetRoundedSize( OldSize ); 00548 NewSize = GetRoundedSize( NewSize ); 00549 00550 if (OldSize == NewSize) 00551 return TRUE; // no change required 00552 00553 if (OldSize < NewSize) 00554 { 00555 ENSURE(FALSE, "Cannot Shrink backwards"); 00556 return FALSE; 00557 } 00558 00559 // lets free up the unwanted bits now 00560 BOOL Result = VirtualFree( ((LPBYTE)MemBase)+NewSize, OldSize-NewSize, MEM_DECOMMIT ); 00561 00562 if (Result==FALSE) 00563 { 00564 TRACEUSER( "Andy", wxT("VirtualFree Shrink from %ld to %ld failed\n"), OldSize, NewSize); 00565 return FALSE; 00566 } 00567 00568 RoundedSize = NewSize; 00569 return TRUE; 00570 00571 #else 00572 // the data will be left alone 00573 ENSURE( FALSE, "Cannot shrink memory blocks"); 00574 return FALSE; 00575 00576 #endif 00577 }
|
|
|
|
|