CDebuggingMemoryManager Class Reference

#include <CDebuggingMemoryManager.h>

List of all members.

Public Member Functions

 CDebuggingMemoryManager (const CDebuggingMemoryManagerSize inSize)
void * getMem (CDebuggingMemoryManagerSize inSize)
bool freeMem (void *)
bool isValid () const

Protected Member Functions

void FreeChunk (lTChunk *inChunk)

Protected Attributes

lTChunkmFreeList
lTChunkmUsedList
lTChunkmBuffer
const long cMagic
const long cUnMagic
long cVM
CMutex mMutex

Friends

ostream & operator<< (ostream &outStream, const CDebuggingMemoryManager &inMem)


Detailed Description

Class for memory management: This class gives you the full control about 1MByte of Memory. What is above will be allocated using the normal techniques. This is nice, if you are doubtful about the Libraries you use.

Definition at line 75 of file CDebuggingMemoryManager.h.


Constructor & Destructor Documentation

CDebuggingMemoryManager::CDebuggingMemoryManager ( const CDebuggingMemoryManagerSize  inSize  ) 

Constructor. The Parameter is the size of the Buffer administered by the structure

A last node, which marks the end for the Chunklist The other lists need no end node

Definition at line 7 of file CDebuggingMemoryManager.cc.

References cMagic, cUnMagic, cVM, mBuffer, lTChunk::mFollowing, mFreeList, lTChunk::mMagic, lTChunk::mNext, lTChunk::mPreceding, lTChunk::mPrev, lTChunk::mSize, and mUsedList.

00007                                                                                         :
00008   mBuffer(new lTChunk[inSize / sizeof(lTChunk) + 2]),
00009   mFreeList(mBuffer),
00010   mUsedList(mBuffer+1),
00011   cMagic(0x1),
00012   cUnMagic(0x2)
00013 {
00014   cVM=0x88414004;
00015 
00016   if(mBuffer)
00017     {
00018       mFreeList=mBuffer;
00019       mUsedList=mBuffer + 1;
00020       mFreeList->mPrev=0;
00021       mFreeList->mNext=mBuffer+2;
00022       mFreeList->mPreceding=0;
00023       mFreeList->mFollowing=mBuffer+1;
00024       mFreeList->mSize=0;
00025       mFreeList->mMagic=cUnMagic;
00026 
00027       mUsedList->mPrev=0;
00028       mUsedList->mNext=0;
00029       mUsedList->mPreceding=mBuffer;
00030       mUsedList->mFollowing=mBuffer+2;
00031       mUsedList->mSize=0;
00032       mUsedList->mMagic=cMagic;
00033 
00034       lTChunk* lFreeChunk=mBuffer+2;
00035       lTChunk* lLastNode=mBuffer+(inSize / sizeof(lTChunk));
00036 
00037       lFreeChunk->mPrev=mBuffer;
00038       lFreeChunk->mNext=0;
00039       lFreeChunk->mPreceding=mBuffer+1;
00040       lFreeChunk->mSize=inSize - sizeof(lTChunk)*3;
00041       lFreeChunk->mFollowing=lLastNode;
00042       lFreeChunk->mMagic=cUnMagic;
00043 
00046       lLastNode->mPrev=0;
00047       lLastNode->mNext=0;
00048       lLastNode->mPreceding=mBuffer+2;
00049       lLastNode->mSize=0;
00050       lLastNode->mFollowing=lLastNode;
00051       lLastNode->mMagic=cMagic;
00052 
00053     }
00054 };


Member Function Documentation

void CDebuggingMemoryManager::FreeChunk ( lTChunk inChunk  )  [protected]

Marking a Chunk as free and deleting him from the list whose member it presently is.

Definition at line 124 of file CDebuggingMemoryManager.cc.

References cMagic, cUnMagic, CMutex::lock(), lTChunk::mMagic, mMutex, lTChunk::mNext, lTChunk::mPrev, and CMutex::unlock().

Referenced by freeMem().

00124                                                        {
00125   mMutex.lock();
00126 
00127   assert(inChunk);
00128   assert(inChunk->mPrev);
00129   assert(inChunk->mMagic==cMagic);
00130 
00131 
00132   if(inChunk->mNext)
00133     inChunk->mNext->mPrev=inChunk->mPrev;
00134 
00135   inChunk->mPrev->mNext=inChunk->mNext;
00136 
00137   inChunk->mMagic=cUnMagic;
00138   mMutex.unlock();
00139 }

void * CDebuggingMemoryManager::getMem ( CDebuggingMemoryManagerSize  inSize  ) 

Getting Mem.

Position of the new occupied chunk

Definition at line 57 of file CDebuggingMemoryManager.cc.

References cMagic, cUnMagic, CMutex::lock(), lTChunk::mFollowing, mFreeList, lTChunk::mMagic, mMutex, lTChunk::mNext, lTChunk::mPreceding, lTChunk::mPrev, lTChunk::mSize, and CMutex::unlock().

Referenced by operator new().

00057                                                                         {
00058   mMutex.lock();
00059   //inSize+=8;
00060 
00061   //Look for first free element of the right size;
00062   lTChunk* lCurrent= mFreeList;
00063 
00064   //For sake of cleanliness.
00065   //The number of Records for the strucure and the memblock
00066   CDebuggingMemoryManagerSize lNumRecords= (inSize + sizeof(lTChunk))/sizeof(lTChunk)+1;
00067   //the corresponding size
00068   CDebuggingMemoryManagerSize lSize= lNumRecords * sizeof(lTChunk) ;
00069 
00070   while(lCurrent && (lCurrent->mSize < lSize))
00071     lCurrent= lCurrent->mNext;
00072 
00073   if(lCurrent){
00074 
00075     assert(lCurrent->mMagic== cUnMagic);
00076     assert(lCurrent->mSize >= lSize);
00077 
00078     //Cut the chunk in two pieces
00079 
00080     lTChunk lNewChunk;
00081 
00082     //the preceding chunk of a free chunk is always occupied
00083     //and  free chunk has always a preceding node:
00084     lNewChunk.mPrev= lCurrent->mPreceding;
00085     lNewChunk.mNext= lNewChunk.mPrev->mNext;
00086     lNewChunk.mPreceding=lCurrent;
00087     lNewChunk.mFollowing=lCurrent->mFollowing;
00088     lNewChunk.mSize= lSize - sizeof(lTChunk);
00089     lNewChunk.mMagic=cMagic;
00090 
00091     CDebuggingMemoryManagerSize lOffset =(lCurrent->mSize/sizeof(lTChunk))- lNumRecords;
00092 
00093     assert(lOffset >= 0);
00094 
00096     lTChunk* lPos= lCurrent
00097       + 1 //lCurrent will not be overwritten
00098       + lOffset;
00099       
00100     assert(lNewChunk.mPrev);
00101 
00102     //A previous node of lCurrent ALWAYS exists, but...
00103     lNewChunk.mPrev->mNext= lPos;
00104     if(lNewChunk.mNext)
00105       lNewChunk.mNext->mPrev= lPos;
00106 
00107     //A chunk here has always a following and preceding chunk
00108     assert(lNewChunk.mFollowing);
00109     lNewChunk.mFollowing->mPreceding= lPos;
00110 
00111     assert(lNewChunk.mPreceding);
00112     lNewChunk.mPreceding->mFollowing= lPos;
00113 
00114     *lPos= lNewChunk;
00115 
00116     lCurrent->mSize -= lSize;
00117 
00118     mMutex.unlock();   
00119     return (void*)(lPos+1);
00120   }else
00121     assert(0);
00122 };

bool CDebuggingMemoryManager::freeMem ( void *  inChunk  ) 

Deleting Mem.

Definition at line 141 of file CDebuggingMemoryManager.cc.

References cMagic, cUnMagic, FreeChunk(), CMutex::lock(), lTChunk::mFollowing, lTChunk::mMagic, mMutex, lTChunk::mNext, lTChunk::mPreceding, lTChunk::mPrev, lTChunk::mSize, and CMutex::unlock().

Referenced by operator delete().

00141                                                   {
00142   mMutex.lock();
00143 
00144   lTChunk* lChunk= ((lTChunk*) inChunk);
00145   lChunk--;
00146 
00147   if(lChunk->mMagic != cMagic){
00148     //Deallocation of something free
00149     mMutex.unlock();
00150     return false;
00151   }else{
00152     //The previous node is free
00153     if(lChunk->mPreceding->mMagic == cUnMagic){
00154       if(lChunk->mFollowing->mMagic == cUnMagic)
00155   {
00156     // both the preceding and the following node are free
00157     // and BOTH EXIST! => Three free nodes -> 1 free node
00158     lTChunk* lNew = lChunk->mPreceding;
00159 
00160     lNew->mSize+= lChunk->mSize 
00161       + lChunk->mFollowing->mSize 
00162       + 2 *sizeof(lTChunk);
00163 
00164     //New pointers to the successors
00165     lNew->mNext=       lChunk->mFollowing->mNext;
00166     lNew->mFollowing = lChunk->mFollowing->mFollowing;
00167 
00168     //New pointers from successors to predecessor
00169     // has to exist because of the termination of the PrecFollow-list
00170     lTChunk* lNextOccupied= lChunk->mFollowing->mFollowing;
00171     assert(lNextOccupied);
00172     {
00173       // The next occupied node exists.
00174       lNextOccupied->mPreceding= lNew;
00175     }
00176     if(lNew->mNext)
00177       lNew->mNext->mPrev=lNew;
00178 
00179   }else{
00180     // only the preceding node is free (and exists)
00181     // Changes of the FreeList and of the PF-list
00182 
00183     lTChunk* lNew = lChunk->mPreceding;
00184 
00185     
00186     lNew->mSize+= lChunk->mSize 
00187       + sizeof(lTChunk);
00188 
00189     lNew->mFollowing = lChunk->mFollowing;
00190     //lNew->mNext stays: The FreeList is not changed
00191 
00192     // has to exist because of the termination of the PrecFollow-list
00193     lTChunk* lNextOccupied= lChunk->mFollowing;
00194     assert(lNextOccupied);
00195     {
00196       // The next occupied node exists.
00197       lNextOccupied->mPreceding= lNew;
00198     }
00199   }
00200       FreeChunk(lChunk);
00201     }else{
00202       if(lChunk->mFollowing->mMagic == cUnMagic){
00203 
00204   //only the following node is free (and exists)
00205 
00206   lTChunk* lFollowing = lChunk->mFollowing;
00207   lChunk->mSize+=     
00208     lFollowing->mSize
00209     +sizeof(lTChunk);
00210   lChunk->mFollowing= lFollowing->mFollowing;
00211 
00212 
00213   //lFollowing out of the PF-List
00214   lFollowing->mFollowing->mPreceding= lChunk;
00215 
00216   //Chunk out of the OccupiedList
00217   FreeChunk(lChunk);
00218 
00219   //Move lChunk into the FreeList
00220   lChunk->mPrev=lFollowing->mPrev;
00221   lFollowing->mPrev->mNext= lChunk;
00222 
00223   // lFollowing out of FreeList
00224   lChunk->mNext= lFollowing->mNext;
00225   if(lChunk->mNext)
00226     lChunk->mNext->mPrev=lChunk;
00227       }else{
00228   //Looking for the next piece of free mem.
00229   lTChunk* lCurrent=lChunk;
00230 
00231   while(lCurrent && (lCurrent->mPreceding->mMagic == cMagic))
00232     lCurrent = lCurrent -> mPreceding;
00233 
00234   //lCurrent has to exist: Either the FreeList-anchor
00235   //or some other piece of free mem.
00236   assert(lCurrent);
00237 
00238   //lChunk out of the Occupied list
00239   FreeChunk(lChunk);
00240 
00241   // According to initialization,
00242   // lCurrent->mPreceding must be a free node.
00243   // and it exsists
00244 
00245   lTChunk* lFree=lCurrent -> mPreceding;
00246   assert(lFree);
00247 
00248   //lChunk into the FreeList
00249   lChunk->mNext=lFree->mNext;
00250   lChunk->mPrev=lFree;
00251   lFree->mNext= lChunk;
00252   if(lChunk->mNext)
00253     lChunk->mNext->mPrev= lChunk;
00254       }
00255     }
00256   }
00257   mMutex.unlock();
00258   return true;
00259 };

bool CDebuggingMemoryManager::isValid (  )  const

Definition at line 261 of file CDebuggingMemoryManager.cc.

References cVM.

Referenced by operator new().

00261                                           {
00262   return cVM==0x88414004;
00263 }


Friends And Related Function Documentation

ostream& operator<< ( ostream &  outStream,
const CDebuggingMemoryManager inMem 
) [friend]

Output for diagnosis.

Definition at line 267 of file CDebuggingMemoryManager.cc.

00267                                                                             {
00268   outStream << endl << "List of free memory chunks" << endl;
00269   {
00270     lTChunk* i=inMem.mFreeList;
00271     while(i && i!=i->mNext){
00272       outStream << i
00273     << ","
00274     << i->mPrev
00275     << ","
00276     << i->mSize
00277     << ","
00278     << i->mMagic%16
00279     << endl;
00280       i=i->mNext;
00281     }
00282 
00283     outStream<< endl << "List of occupied memory chunks" << endl;
00284 
00285     i=inMem.mUsedList;
00286     while(i && i!=i->mNext){
00287       outStream << i
00288     << ","
00289     << i->mPrev
00290     << ","
00291     << i->mSize
00292     << ","
00293     << i->mMagic%16
00294     << endl;
00295       i=i->mNext;
00296     }
00297 
00298     outStream << endl << "PrecedingFollowList" << endl;
00299 
00300     i=inMem.mFreeList;
00301     while(i!=i->mFollowing){
00302       outStream << i
00303     << ","
00304     << i->mPreceding
00305     << ","
00306     << i->mSize
00307     << ","
00308     << i->mMagic%16
00309     << endl;
00310       i=i->mFollowing;
00311     }
00312     {
00313       outStream << i
00314     << ","
00315     << i->mPreceding
00316     << ","
00317     << i->mSize
00318     << ","
00319     << i->mMagic%16
00320     << endl;
00321       i=i->mFollowing;
00322     }
00323 
00324     outStream << "END" << endl;
00325     i=inMem.mBuffer+(50000 / sizeof(lTChunk));
00326 
00327 
00328     outStream << "Terminator" << endl;
00329     outStream << i 
00330         << "," 
00331         << i->mPreceding 
00332         << ","
00333         << i->mSize
00334         << ","
00335         << i->mMagic%16
00336         << endl;
00337   }
00338   return outStream;
00339 };


Member Data Documentation

List of free memory chunks.

Definition at line 83 of file CDebuggingMemoryManager.h.

Referenced by CDebuggingMemoryManager(), getMem(), and operator<<().

List of used memory chunks.

Definition at line 85 of file CDebuggingMemoryManager.h.

Referenced by CDebuggingMemoryManager(), and operator<<().

THE memory used by this memory administrator.

Definition at line 88 of file CDebuggingMemoryManager.h.

Referenced by CDebuggingMemoryManager(), and operator<<().

const long CDebuggingMemoryManager::cMagic [protected]

The magic number for valid lTChunk nodes

Definition at line 91 of file CDebuggingMemoryManager.h.

Referenced by CDebuggingMemoryManager(), FreeChunk(), freeMem(), and getMem().

const long CDebuggingMemoryManager::cUnMagic [protected]

The magic number to invalidate lTChunk nodes

Definition at line 93 of file CDebuggingMemoryManager.h.

Referenced by CDebuggingMemoryManager(), FreeChunk(), freeMem(), and getMem().

long CDebuggingMemoryManager::cVM [protected]

Definition at line 96 of file CDebuggingMemoryManager.h.

Referenced by CDebuggingMemoryManager(), and isValid().

for multithreading

Definition at line 98 of file CDebuggingMemoryManager.h.

Referenced by FreeChunk(), freeMem(), and getMem().


The documentation for this class was generated from the following files:

Generated on Wed Jan 7 00:31:07 2009 for Gift by  doxygen 1.5.6