Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PsnSharedMemoryManager.cxx

Go to the documentation of this file.
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 }

logo OpenMask

Documentation generated on Mon Nov 25 15:25:01 2002

Generated with doxygen 1.2.12 by Dimitri van Heesch ,   1997-2001