MemoryBlock Class Reference

#include <memblk.h>

List of all members.

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


Detailed Description

Definition at line 123 of file memblk.h.


Constructor & Destructor Documentation

MemoryBlock::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.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/3/94
Parameters:
- [INPUTS]
Returns:
-

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 }

MemoryBlock::~MemoryBlock  ) 
 

Destructor. Doesn't do anything really, though might do a DeInit one day.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/3/94
Parameters:
- [INPUTS]
Returns:
-
See also:
MemoryBlock::DeInit

Definition at line 171 of file memblk.cpp.

00172 {
00173 }


Member Function Documentation

void MemoryBlock::DeInit void   ) 
 

Frees up any allocations on this memory block. Should always be called during exit for a tidy cleanup.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/3/94
Parameters:
- [INPUTS]
Returns:
-

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 }

UINT32 MemoryBlock::GetRoundedSize UINT32  RawSize  )  [inline]
 

Definition at line 137 of file memblk.h.

00138     {
00139         return( ( RawSize + 4096 - 1 ) & ~4095 );
00140     }

BOOL MemoryBlock::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.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/2/94
Parameters:
OldSize size it is at the moment [INPUTS] NewSize desired size of new block Pointer where new pointer is to be stored
Returns:
TRUE if worked, FALSE if failed
See also:
DoGrowGlobalHeap;MemoryBlock::Shrink

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 }

LPVOID MemoryBlock::Init INT32  InitSize,
BOOL  bAutoZero,
MemoryBlockType  Type
 

Sets up block for subsequent allocations.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/3/94
Parameters:
InitSize initial size of block required [INPUTS] bAutoZero TRUE if new memory required to be zeroed Type one of MEMORYBLOCK_xxx constants. Determines maximum size of block.
Returns:
Pointer to memory if worked, NULL if failed to initialise.

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 }

BOOL MemoryBlock::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.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/3/94
Parameters:
OldSize size it is at the moment [INPUTS] NewSize desired size of new block, smaller than OldSize Pointer where new pointer is to be stored
Returns:
TRUE if worked, FALSE if failed
See also:
MemoryBlock::Grow

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 }


Member Data Documentation

PVOID MemoryBlock::m_pMemBlk [private]
 

Definition at line 152 of file memblk.h.

UINT32 MemoryBlock::m_RoundedSize [private]
 

Definition at line 151 of file memblk.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:56:10 2007 for Camelot by  doxygen 1.4.4