00001 #include "PsnThreadMemoryManager.h" 00002 00003 #include "PsnMemoryElementDescriptor.h" 00004 #include <assert.h> 00005 #include <iostream> 00006 #include "PsnSharedMemoryManager.h" 00007 00008 #include "PsnDescriptorMemoryManager.h" 00009 //#define _DEBUGMEMORYMANAGEMENT 00010 00011 list <void *> & PsnThreadMemoryManager::getListOfDetachedMemoryBlocks () 00012 { 00013 static list <void *> designPattern ; 00014 return designPattern ; 00015 } 00016 00017 list <pair <void *, PsnThreadMemoryManager *> > & PsnThreadMemoryManager::getListOfLeakedMemoryBlocks () 00018 { 00019 static list <pair <void *, PsnThreadMemoryManager *> > designPattern ; 00020 return designPattern ; 00021 } 00022 00023 PsnMutexLock & PsnThreadMemoryManager::getFreedMemoryBlocksMutex() 00024 { 00025 static PsnMutexLock toto ; 00026 return toto ; 00027 } 00028 PsnMutexLock & PsnThreadMemoryManager::getLeakedMemoryBlocksMutex() 00029 { 00030 static PsnMutexLock toto ; 00031 return toto ; 00032 } 00033 00034 void PsnThreadMemoryManager::freeLeakedMemoryBlocks () 00035 { 00036 getFreedMemoryBlocksMutex().protect() ; 00037 list <void *> & mylist ( getListOfDetachedMemoryBlocks () ) ; 00038 for ( list <void *>::iterator i = mylist.begin() ; 00039 i != mylist.end() ; 00040 i = mylist.erase (i) ) 00041 { 00042 PsnMemoryManager * correctMemoryManager = PsnMemoryManager::whichMemoryManager ( *i ) ; 00043 correctMemoryManager->freeSizeRemembered ( *i ) ; 00044 } 00045 getFreedMemoryBlocksMutex().unprotect() ; 00046 getLeakedMemoryBlocksMutex().protect() ; 00047 list <pair <void *, PsnThreadMemoryManager *> > & alist ( getListOfLeakedMemoryBlocks () ) ; 00048 for ( list <pair <void *, PsnThreadMemoryManager *> >::iterator i = alist.begin() ; 00049 i != alist.end() ; 00050 i = alist.erase (i) ) 00051 { 00052 (*i).second->mfreeSizeRememberedOtherThread ( (*i).first ) ; 00053 } 00054 getLeakedMemoryBlocksMutex().unprotect() ; 00055 } 00056 00057 00058 00059 PsnThreadMemoryManager::~PsnThreadMemoryManager() 00060 { 00061 } 00062 00063 00064 PsnThreadMemoryManager::PsnThreadMemoryManager ( void *startDsm, 00065 size_t sizeDsm, 00066 PsnMemoryManager & rawMemoryProvider, 00067 PsnMemoryManager & descriptorMemoryProvider ) : 00068 PsnMemoryManager(), 00069 _memoryManaged ( sizeDsm ), 00070 _rawMemoryProvider ( rawMemoryProvider ), 00071 _descriptorMemoryProvider ( descriptorMemoryProvider ), 00072 _freeMemoryZones ( new(&descriptorMemoryProvider) PsnMemoryElementDescriptor ( ) ), 00073 _managedMemoryZones ( new(&descriptorMemoryProvider) PsnMemoryElementDescriptor ( ) ), 00074 _user ( pthread_self() ) 00075 { 00076 // the getFromFree member function relies on that 00077 assert ( startDsm != 0 ) ; 00078 00079 _managedMemoryZones->base = (unsigned int) startDsm ; 00080 _managedMemoryZones->size = sizeDsm ; 00081 _managedMemoryZones->next = 0 ; 00082 00083 _freeMemoryZones->base = (unsigned int) startDsm ; 00084 _freeMemoryZones->size = sizeDsm ; 00085 _freeMemoryZones->next = 0 ; 00086 } 00087 00088 00089 00090 void * PsnThreadMemoryManager::allocateSizeRemembered (size_t size) 00091 { 00092 #ifdef _DEBUGMEMORYMANAGEMENT 00093 assert ( _user == pthread_self() ) ; 00094 #endif 00095 size_t sizeNeeded = sizeof(size_t) + size ; 00096 void * result = getFromFree ( sizeNeeded ) ; 00097 //cerr<<"PsnThreadMemoryManager::allocateSizeRemembered "<<result<<endl; 00098 if ( result == NULL ) 00099 { 00100 PsnMemoryElementDescriptor * iNew ; 00101 00102 //allocate more memory 00103 result = _rawMemoryProvider.allocateSizeRemembered ( _memoryManaged ) ; 00104 if ( result != NULL) 00105 { 00106 iNew = new (& _descriptorMemoryProvider) PsnMemoryElementDescriptor(); 00107 iNew->base = (unsigned int)result ; 00108 iNew->size = _memoryManaged ; 00109 iNew->next = 0 ; 00110 _managedMemoryZones->next = (unsigned int) iNew ; 00111 00112 addInFree (result, _memoryManaged ) ; 00113 _memoryManaged += _memoryManaged ; 00114 00115 //retry 00116 result = allocateSizeRemembered ( sizeNeeded ) ; 00117 } 00118 else 00119 {//allocation has failed, try minimum allocation 00120 result = _rawMemoryProvider.allocateSizeRemembered ( sizeNeeded ) ; 00121 if ( result != NULL) 00122 { 00123 iNew = new (& _descriptorMemoryProvider) PsnMemoryElementDescriptor(); 00124 iNew->base = (unsigned int)result ; 00125 iNew->size = sizeNeeded; 00126 iNew->next = 0 ; 00127 _managedMemoryZones->next = (unsigned int) iNew ; 00128 00129 addInFree (result, sizeNeeded ) ; 00130 _memoryManaged += sizeNeeded ; 00131 00132 //retry 00133 result = allocateSizeRemembered ( sizeNeeded ) ; 00134 } 00135 } 00136 } 00137 if (result != NULL) 00138 { 00139 *((size_t *)result) = size; 00140 00141 result = (void *) ((unsigned int)result + sizeof (size_t ) ) ; 00142 } 00143 return result ; 00144 } 00145 00146 00147 00148 void PsnThreadMemoryManager::mfreeSizeRememberedOtherThread ( void * ptr ) 00149 { 00150 #ifdef _DEBUGMEMORYALLOCATION 00151 inAdressSpace ( ptr) ; 00152 #endif 00153 size_t * addressOfSize = (size_t *) ((unsigned int)ptr - sizeof ( size_t ) ) ; 00154 addInFree ( (void *)addressOfSize, *addressOfSize + sizeof ( size_t ) ) ; 00155 } 00156 00157 00158 00159 void PsnThreadMemoryManager::freeSizeRemembered ( void * ptr ) 00160 { 00161 //cerr<<"PsnThreadMemoryManager::freeSizeRemembered "<<pthread_self()<<endl; 00162 if ( _user == pthread_self() ) 00163 { 00164 if (inAdressSpace ( ptr) ) 00165 { 00166 size_t * addressOfSize = (size_t *) ((unsigned int)ptr - sizeof ( size_t ) ) ; 00167 addInFree ( (void *)addressOfSize, *addressOfSize + sizeof ( size_t ) ) ; 00168 } 00169 else 00170 { 00171 if ( _descriptorMemoryProvider.inAdressSpace ( ptr ) ) 00172 { 00173 _descriptorMemoryProvider.freeSizeRemembered( ptr ) ; 00174 } 00175 else 00176 { 00177 getFreedMemoryBlocksMutex().protect() ; 00178 getListOfDetachedMemoryBlocks().push_back ( ptr ) ; 00179 getFreedMemoryBlocksMutex().unprotect() ; 00180 } 00181 } 00182 } 00183 else 00184 { 00185 getLeakedMemoryBlocksMutex().protect() ; 00186 getListOfLeakedMemoryBlocks().push_back ( make_pair ( ptr, this) ) ; 00187 getLeakedMemoryBlocksMutex().unprotect() ; 00188 } 00189 } 00190 00191 void * PsnThreadMemoryManager::getFromFree ( size_t size ) 00192 { 00193 #ifdef _DEBUGMEMORYMANAGEMENT 00194 assert ( _user == pthread_self() ) ; 00195 //integrity check 00196 PsnMemoryElementDescriptor * test = _freeMemoryZones ; 00197 while (test != 0) 00198 { 00199 assert (inAdressSpace ( ( PsnMemoryElementDescriptor *)test->base ) ) ; 00200 assert ( test != ( PsnMemoryElementDescriptor *)test->next ) ; 00201 if ( test->next != 0) 00202 { 00203 assert ( ((PsnMemoryElementDescriptor *)test->next)->base > test->base + test->size ) ; 00204 } 00205 test = ( PsnMemoryElementDescriptor *)test->next ; 00206 } 00207 #endif 00208 PsnMemoryElementDescriptor *i , *pred ; 00209 00210 unsigned int addr ; 00211 00212 00213 i = _freeMemoryZones ; 00214 00215 pred = NULL ; 00216 00217 addr = 0 ; 00218 00219 while ( i != NULL ) 00220 { 00221 if ( i->size >= size ) /* First fit strategy */ 00222 { 00223 addr = i->base ; 00224 if ( i->size == size ) 00225 { 00226 if ( pred == NULL ) 00227 { 00228 PsnMemoryElementDescriptor * newStartFreeList = (PsnMemoryElementDescriptor *) i -> next ; 00229 delete _freeMemoryZones ; 00230 _freeMemoryZones = newStartFreeList ; 00231 } 00232 else 00233 { 00234 pred->next = i->next ; 00235 delete ( i ) ; 00236 } 00237 } 00238 else 00239 { 00240 i->base = i->base + size ; 00241 i->size = i->size - size ; 00242 } 00243 i = NULL ; 00244 } 00245 else 00246 { 00247 pred = i ; 00248 i = (PsnMemoryElementDescriptor *) i->next ; 00249 } 00250 } 00251 #ifdef _DEBUGMEMORYMANAGEMENT 00252 //integrity check 00253 test = _freeMemoryZones ; 00254 while (test != 0) 00255 { 00256 assert (inAdressSpace ( ( PsnMemoryElementDescriptor *)test->base ) ) ; 00257 assert ( test != ( PsnMemoryElementDescriptor *)test->next ) ; 00258 if ( test->next != 0) 00259 { 00260 assert ( ((PsnMemoryElementDescriptor *)test->next)->base > test->base + test->size ) ; 00261 } 00262 test = ( PsnMemoryElementDescriptor *)test->next ; 00263 } 00264 #endif 00265 if (addr == 0 ) //no correct memory zone was found 00266 { 00267 return NULL ; 00268 } 00269 else 00270 { 00271 return (void *)addr ; 00272 } 00273 #ifdef _DEBUGMEMORYMANAGEMENT 00274 cerr<<"PsnThreadMemoryManager:"<<this<<":addInFree: ("<<(void *)addr<<","<<size<<")"<<endl; 00275 #endif 00276 } 00277 00278 00279 00280 void PsnThreadMemoryManager::addInFree(void * ptr, size_t size) 00281 { 00282 #ifdef _DEBUGMEMORYMANAGEMENT 00283 assert ( _user == pthread_self() ) ; 00284 //integrity check 00285 PsnMemoryElementDescriptor * test = _freeMemoryZones ; 00286 while (test != 0) 00287 { 00288 assert (inAdressSpace ( ( PsnMemoryElementDescriptor *)test->base ) ) ; 00289 assert ( test != ( PsnMemoryElementDescriptor *)test->next ) ; 00290 if ( test->next != 0) 00291 { 00292 assert ( ((PsnMemoryElementDescriptor *)test->next)->base > test->base + test->size ) ; 00293 } 00294 test = ( PsnMemoryElementDescriptor *)test->next ; 00295 } 00296 #endif 00297 #ifdef _DEBUGMEMORYMANAGEMENT 00298 cerr<<"PsnThreadMemoryManager:"<<this<<":addInFree: ("<<ptr<<","<<size<<")"<<endl; 00299 #endif 00300 PsnMemoryElementDescriptor *l, *iNew, *tmp ; 00301 00302 iNew = new(& _descriptorMemoryProvider) PsnMemoryElementDescriptor(); 00303 iNew->base = (unsigned int)ptr ; 00304 iNew->size = size; 00305 00306 if ( _freeMemoryZones == NULL) 00307 { /* No free memory in the memory manager */ 00308 iNew->next = (unsigned int) NULL ; 00309 _freeMemoryZones = iNew ; 00310 } 00311 else 00312 { 00313 l = _freeMemoryZones ; 00314 if ( l->base > iNew->base ) 00315 { 00316 /* iNew is the lowest interval */ 00317 iNew->next = (unsigned int) _freeMemoryZones ; 00318 _freeMemoryZones = iNew ; 00319 //reorder so that l->next == iNew for merge test 00320 l = iNew ; 00321 iNew = (PsnMemoryElementDescriptor *) l->next ; 00322 } 00323 else 00324 { 00325 /* Search the immediate lower interval */ 00326 tmp = (PsnMemoryElementDescriptor * ) l -> next ; 00327 bool onBoucle = ( tmp != NULL ) ; 00328 if (onBoucle ) 00329 { 00330 onBoucle = ( iNew->base > tmp->base ) ; 00331 } 00332 while ( onBoucle ) 00333 { 00334 l = tmp ; 00335 tmp = (PsnMemoryElementDescriptor * ) l->next ; 00336 if (tmp != NULL) 00337 { 00338 onBoucle = iNew->base > tmp->base ; 00339 } 00340 else 00341 { 00342 onBoucle = false ; 00343 } 00344 } 00345 00346 iNew->next = (unsigned int) tmp ; 00347 l->next = (unsigned int) iNew ; 00348 if ( tmp != NULL ) 00349 { 00350 //try to merge the the new free zone with the following free zonee 00351 if (iNew->base + iNew->size == tmp -> base) 00352 { 00353 #ifdef _DEBUGMEMORYMANAGEMENT 00354 cerr<<"Merging new free zone ("<<ptr<<") with following"<<endl; 00355 #endif 00356 iNew->size += tmp->size ; 00357 iNew->next = tmp->next ; 00358 delete tmp ; 00359 } 00360 } 00361 } 00362 if ( l->base + l->size == iNew->base ) 00363 { 00364 //try and merger the preceeding free memory block with the freed one 00365 #ifdef _DEBUGMEMORYMANAGEMENT 00366 cerr<<"Merging new free zone ("<<ptr<<") with preceeding"<<endl; 00367 #endif 00368 l->size += iNew->size ; 00369 l->next = iNew->next ; 00370 if (_freeMemoryZones == iNew) 00371 { 00372 _freeMemoryZones = l; 00373 } 00374 delete iNew ; 00375 } 00376 } 00377 #ifdef _DEBUGMEMORYMANAGEMENT 00378 //integrity check 00379 test = _freeMemoryZones ; 00380 while (test != 0) 00381 { 00382 assert (inAdressSpace ( ( PsnMemoryElementDescriptor *)test->base ) ) ; 00383 assert ( test != ( PsnMemoryElementDescriptor *)test->next ) ; 00384 if ( test->next != 0) 00385 { 00386 assert ( ((PsnMemoryElementDescriptor *)test->next)->base > test->base + test->size ) ; 00387 } 00388 test = ( PsnMemoryElementDescriptor *)test->next ; 00389 } 00390 #endif 00391 } 00392 00393 00394 bool PsnThreadMemoryManager::inAdressSpace ( void * ptr ) const 00395 { 00396 bool result = false ; 00397 unsigned int adress = (unsigned int ) ptr ; 00398 PsnMemoryElementDescriptor * current = _managedMemoryZones ; 00399 while ( (! result) && ( current != NULL ) ) 00400 { 00401 result = current->inAdressSpace ( adress ) ; 00402 current = (PsnMemoryElementDescriptor *) current->next ; 00403 } 00404 return result ; 00405 } 00406 00407
| Documentation generated on Mon Nov 25 15:25:01 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |