#include <CDebuggingMemoryManager.h>
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 | |
| lTChunk * | mFreeList |
| lTChunk * | mUsedList |
| lTChunk * | mBuffer |
| const long | cMagic |
| const long | cUnMagic |
| long | cVM |
| CMutex | mMutex |
Friends | |
| ostream & | operator<< (ostream &outStream, const CDebuggingMemoryManager &inMem) |
Definition at line 75 of file CDebuggingMemoryManager.h.
| 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 };
| 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 }
| 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 };
lTChunk* CDebuggingMemoryManager::mFreeList [protected] |
List of free memory chunks.
Definition at line 83 of file CDebuggingMemoryManager.h.
Referenced by CDebuggingMemoryManager(), getMem(), and operator<<().
lTChunk* CDebuggingMemoryManager::mUsedList [protected] |
List of used memory chunks.
Definition at line 85 of file CDebuggingMemoryManager.h.
Referenced by CDebuggingMemoryManager(), and operator<<().
lTChunk* CDebuggingMemoryManager::mBuffer [protected] |
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().
CMutex CDebuggingMemoryManager::mMutex [protected] |
for multithreading
Definition at line 98 of file CDebuggingMemoryManager.h.
Referenced by FreeChunk(), freeMem(), and getMem().
1.5.6