00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 #include <PsnSharedMemoryManager.h> 00019 #include <unistd.h> 00020 #include <iostream> 00021 #include <assert.h> 00022 #include <PsnNew.h> 00023 #include <PsNoMemoryAvailableException.h> 00024 00025 00026 #ifdef _MOME 00027 #include "PsnMemoryElementDescriptor.h" 00028 #include <PsMomeController.h> 00029 //#include <PsnLock.h> 00030 #include <MomeDsm.h> 00031 #endif 00032 00033 00034 00035 PsnSharedMemoryManager::PsnSharedMemoryManager(void *startDsm, 00036 size_t sizeDsm, 00037 size_t pageSize, 00038 size_t alignedSize) : 00039 _sizeDsm(sizeDsm) , 00040 _startDsm((unsigned int)startDsm) , 00041 _pageSize(pageSize) , 00042 _alignedSize(alignedSize) , 00043 _numberOfLocks(0) , 00044 _locked(false) 00045 { 00046 _freed.first=NULL; 00047 } 00048 00049 PsnSharedMemoryManager::~PsnSharedMemoryManager() 00050 { 00051 } 00052 00053 00054 void PsnSharedMemoryManager::handOver(void * pointer, size_t allocatedSize, size_t sizeBefore, size_t sizeAfter) { 00055 cerr<<"Warning : Memory is being lost by PsnSharedMemoryManager::handOver"<<endl; 00056 } 00057 00058 00059 void * PsnSharedMemoryManager::mfastmalloc(size_t size) { 00060 #ifdef _DEBUGALLOCATIONMOME 00061 cerr<<"PsnSharedMemoryManager::mfastmalloc "<<size<<endl; 00062 #endif 00063 void * resul; 00064 if( _freed.first != NULL ) { 00065 if (( _freed.second - _pageSize < size ) && 00066 (size <= _freed.second ) ) { 00067 00068 resul = _freed.first; 00069 _freed.first = NULL; 00070 00071 } 00072 else { 00073 lockIfNeeded(); 00074 #ifdef _DEBUGALLOCATIONMOME 00075 cerr<<"PsnSharedMemoryManager::mfastmalloc libération de " 00076 <<globalAddressToLocal(_freed.first) 00077 <<" " 00078 <<_freed.second 00079 <<endl; 00080 #endif 00081 mfree(_freed.first,_freed.second); 00082 _freed.first=NULL; 00083 resul=mmalloc(size); 00084 #ifdef _DEBUGALLOCATIONMOME 00085 cerr<<"PsnSharedMemoryManager::mfastmalloc reallocation de " 00086 <<globalAddressToLocal(resul) 00087 <<" " 00088 <<size 00089 <<endl; 00090 #endif 00091 unlockIfNeeded(); 00092 } 00093 } 00094 else { 00095 lockIfNeeded(); 00096 #ifdef _DEBUGALLOCATIONMOME 00097 cerr<<"PsnSharedMemoryManager::mfastmalloc : rien de dispo pour une allocation rapide"<<endl; 00098 #endif 00099 resul=mmalloc(size); 00100 unlockIfNeeded(); 00101 } 00102 return resul; 00103 } 00104 00105 void PsnSharedMemoryManager::mfastfree ( void *addr , size_t size) { 00106 #ifdef _DEBUGALLOCATIONMOME 00107 cerr<<"PsnSharedMemoryManager::mfastfree"<<endl; 00108 #endif 00109 if (_freed.first!=NULL) {//précedent freed needs to be really freeded 00110 lockIfNeeded(); 00111 #ifdef _DEBUGALLOCATIONMOME 00112 cerr<<"PsnSharedMemoryManager::mfastfree : il faut vraiment libérer " 00113 <<globalAddressToLocal(_freed.first)<<endl; 00114 #endif 00115 mfree(_freed.first,_freed.second); 00116 unlockIfNeeded(); 00117 } 00118 #ifdef _DEBUGALLOCATIONMOME 00119 else { 00120 cerr<<"PsnSharedMemoryManager::mfastfree : rien a vraiment libérer "<<endl; 00121 } 00122 #endif 00123 _freed.first=addr; 00124 _freed.second=alignedSize(size); 00125 } 00126 00127 00128 void PsnSharedMemoryManager::showMemory ( void ) { 00129 cerr<<"PsnSharedMemoryManager::showMemory "<<endl; 00130 } 00131 00132 00133 void * PsnSharedMemoryManager::mmalloc(size_t size) { 00134 #ifdef _DEBUGALLOCATIONMOME 00135 cerr<<"PsnSharedMemoryManager::mmalloc"<<endl; 00136 #endif 00137 //cout <<_locked<<" "<<! lockNeeded()<<" "<<size<<endl; 00138 assert( _locked || ! lockNeeded () ); 00139 00140 size_t allocatedSize=alignedSize(size); 00141 00142 void * begin ; 00143 00144 assert(allocatedSize>=size); 00145 00146 begin = getFromFree ( allocatedSize ); 00147 00148 if ( invalidOffset ( globalAddressToLocal( begin ) ) ) { 00149 00150 //cerr<<"PsnSharedMemoryManager::mmalloc génération d'une exception "<<allocatedSize<<endl; 00151 00152 HeapStackTop usualContext(0); 00153 00154 PsNoMemoryAvailableException error("PsnSharedMemoryManager::mmalloc ",allocatedSize) ; 00155 00156 throw error ; 00157 } 00158 00159 // char * toZero = (char *)begin; 00160 // for (int i=0 ; i<allocatedSize ; i++) { 00161 // toZero[i] = 0 ; 00162 // } 00163 00164 #ifdef _DEBUGALLOCATIONMOME 00165 cerr<<"FILE "<<MomeInternalDate()<<" + "<<allocatedSize<<" , "<<globalAddressToLocal(begin)<<endl; 00166 cerr<<begin<<" "<<allocatedSize<<endl; 00167 #endif 00168 00169 return begin; 00170 00171 } 00172 00173 00174 void PsnSharedMemoryManager::mfree(void *addr, size_t size) { 00175 00176 assert(_locked || !lockNeeded() ); 00177 00178 size_t allocatedSize=alignedSize(size); 00179 00180 #ifdef _DEBUGALLOCATIONMOME 00181 cerr<<"FILE "<<MomeInternalDate()<<" - "<<allocatedSize<<" , "<<globalAddressToLocal(addr)<<endl; 00182 #endif 00183 00184 addInFree ( addr , allocatedSize ) ; 00185 #ifdef _DEBUGALLOCATIONMOME 00186 cerr<<"PsnSharedMemoryManager::"<<this<<"::mfree fait"<<endl; 00187 #endif 00188 } 00189 00190 00191 void * PsnSharedMemoryManager::allocateSizeRemembered (size_t size) { 00192 00193 void * resul; 00194 00195 lockIfNeeded(); 00196 00197 size_t sizeOfOffsetForSize = alignedSize( sizeof(size_t) ); 00198 00199 resul = mmalloc( size + sizeOfOffsetForSize ); 00200 00201 if (resul != NULL) { 00202 *((size_t *)resul)=size; 00203 00204 unlockIfNeeded(); 00205 00206 return ( (void *) ((unsigned int)resul + sizeOfOffsetForSize ) ) ; 00207 } 00208 else { 00209 return NULL ; 00210 } 00211 } 00212 00213 00214 void PsnSharedMemoryManager::freeSizeRemembered(void * ptr) 00215 { 00216 size_t size; 00217 00218 if ( inAdressSpace ( ptr ) ) 00219 { 00220 #ifdef _DEBUGALLOCATIONMOME 00221 cerr<<"Utilisation de notre free "<<endl; 00222 #endif 00223 lockIfNeeded(); 00224 00225 size_t sizeOfOffsetForSize = alignedSize( sizeof(size_t) ); 00226 00227 size_t * addressOfSize = (size_t *)((unsigned int)ptr - sizeOfOffsetForSize ); 00228 00229 size = *addressOfSize; 00230 00231 mfree( addressOfSize , size + sizeOfOffsetForSize ); 00232 00233 unlockIfNeeded() ; 00234 } 00235 else 00236 { 00237 PsnMemoryManager * correctMemoryManager = whichMemoryManager( ptr ) ; 00238 correctMemoryManager->freeSizeRemembered( ptr ) ; 00239 } 00240 } 00241 00242 00243 //----------------------- lock management -------------------------// 00244 00245 00246 void PsnSharedMemoryManager::lockIfNeeded() { 00247 00248 _accessToLockData.protect(); 00249 00250 while (_locked && (_lockedBy != pthread_self() ) ) { 00251 #ifdef _DEBUGLOCK 00252 cerr<<" PsnSharedMemoryManager::lockIfNeeded() : waiting for thread"<<_lockedBy<<endl; 00253 #endif 00254 _conditionOnLocked.waitForChange(_accessToLockData) ; 00255 } 00256 00257 _numberOfLocks++; 00258 00259 if(!_locked) { 00260 00261 if( lockNeeded() ) { 00262 #ifdef _DEBUGLOCK 00263 cerr<<"PsnSharedMemoryManager::"<<this<<"::lockIfNeeded("; 00264 cerr.flush() ; 00265 #endif 00266 00267 lock(); 00268 00269 _locked = true; 00270 _lockedBy = pthread_self() ; 00271 #ifdef _DEBUGLOCK 00272 cerr<<") effectif pour "<<_lockedBy<<endl; 00273 #endif 00274 } 00275 } 00276 00277 _accessToLockData.unprotect(); 00278 00279 } 00280 00281 00282 void PsnSharedMemoryManager::unlockIfNeeded() { 00283 00284 _accessToLockData.protect(); 00285 00286 _numberOfLocks--; 00287 00288 if ( _locked && ( _numberOfLocks == 0 ) ) { 00289 00290 if( lockNeeded ( ) ) { 00291 00292 #ifdef _DEBUGLOCK 00293 cerr<<"PsnSharedMemoryManager::"<<this<<"::unlockIfNeeded("; 00294 #endif 00295 unlock(); 00296 #ifdef _DEBUGLOCK 00297 cerr<<") effectif pour"<<_lockedBy<<endl; 00298 #endif 00299 _locked=false; 00300 _accessToLockData.unprotect(); 00301 _conditionOnLocked.signalChange () ; 00302 } 00303 else { 00304 _accessToLockData.unprotect(); 00305 } 00306 } 00307 else { 00308 _accessToLockData.unprotect(); 00309 } 00310 } 00311 00312 bool PsnSharedMemoryManager::locked() const { 00313 00314 return _locked; 00315 00316 } 00317 00318 00319 //--------------------------- Adress, alignement and page manipulation -----// 00320 00321 00322 unsigned int PsnSharedMemoryManager::getAnInvalidOffset() const { 00323 00324 return _sizeDsm; 00325 00326 } 00327 00328 00329 bool PsnSharedMemoryManager::invalidOffset(unsigned int offset) const { 00330 00331 return offset >= _sizeDsm; 00332 00333 } 00334 00335 00336 size_t PsnSharedMemoryManager::pageSize() const { 00337 00338 return _pageSize; 00339 00340 } 00341 00342 00343 size_t PsnSharedMemoryManager::alignedSize(size_t size) { 00344 00345 size_t allocatedSize; 00346 00347 if ( size % _alignedSize != 0 ) { 00348 00349 allocatedSize = ( size / _alignedSize + 1 ) * _alignedSize; 00350 00351 } 00352 else { 00353 00354 allocatedSize = size; 00355 00356 } 00357 00358 return allocatedSize; 00359 00360 }
| Documentation generated on Mon Nov 25 15:25:01 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |