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

PsnCoherantMemoryManager.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 #ifdef _MOME
00019 #include <PsnCoherantMemoryManager.h>
00020 
00021 #include <PsnMemoryElementDescriptor.h>
00022 #include <PsnUniqueCreator.h>
00023 #include <PsnLock.h>
00024 
00025 
00026 PsnCoherantMemoryManager::PsnCoherantMemoryManager(void *startDsm, size_t sizeDsm, size_t pageSize) : 
00027    PsnSharedMemoryManager(startDsm, sizeDsm, pageSize, 4) ,
00028    uniqueCreatorDataOffset (sizeof(PsnMemoryElementDescriptor) + sizeof(unsigned int) )  {
00029 
00030    MomeConsistencyOfRegion (startDsm,
00031                             sizeDsm,
00032                             MomeStrongConsistency,
00033                             MomeRegionBlockingProtocol,
00034                             0);
00035 
00036 #ifdef _DEBUGPAGEFAULTS
00037    MomeSetRegionAttributes ((void *)_startDsm,
00038                             (long)_sizeDsm,
00039                             MomeTraceTransitions);
00040 #endif
00041 
00042    _myLock= new PsnLock();
00043 
00044    MomeManageLock(_myLock->getLock(),0);
00045 
00046    _memoryElementDescriptorMemoryManager = this ;
00047 
00048    lockIfNeeded();
00049    
00050    if(MomeMe==0) {
00051          // lors de la première tentative, 
00052          // on fait l'allocation à la main
00053       _freeMem = (PsnMemoryElementDescriptor *)(_startDsm + sizeof(unsigned int) ) ;
00054       _freeMem->base = sizeof(PsnMemoryElementDescriptor) + sizeof(unsigned int) ;
00055       _freeMem->size = sizeDsm - sizeof(PsnMemoryElementDescriptor) - sizeof(unsigned int) ;
00056       _freeMem->next = getAnInvalidOffset() ;
00057       setFreeMem(_freeMem);
00058    }
00059       
00060    //allocation à l'offset uniqueCreatorDataOffset du bloc utilisé pour PsnUniqueCreatorData
00061    //Il sera récupéré par le new du PsnUniqueCreatorData
00062  
00063    if(MomeMe==0) {
00064       cerr<<"titi"<<endl;
00065       unsigned int verif = (unsigned int)mmalloc(sizeof(PsnUniqueCreatorData)) - _startDsm ;
00066       if(verif != uniqueCreatorDataOffset) {
00067          cout<<"PsnCoherantMemoryManager::PsnCoherantMemoryManager Offset Réelle de uniqueCreatorDataOffset : "
00068              <<verif
00069              <<" et non "
00070              <<uniqueCreatorDataOffset<<endl;
00071          PsController::error("Il faut mieux s'arrêter vu l'erreur précédante");
00072       }
00073    }
00074    
00075    unlockIfNeeded() ;
00076 
00077 }
00078 
00079 PsnCoherantMemoryManager::~PsnCoherantMemoryManager() {
00080 
00081 }
00082 
00083 void PsnCoherantMemoryManager::lock() {
00084 #ifdef _DEBUGLOCK
00085    cerr<<(int)_myLock->getLock();
00086 #endif
00087    MomeMutexLock(_myLock->getLock()); 
00088 } 
00089 
00090 void PsnCoherantMemoryManager::unlock() {
00091 #ifdef _DEBUGLOCK
00092    cerr<<(int)_myLock->getLock();
00093 #endif
00094    MomeMutexUnLock(_myLock->getLock());
00095 }
00096 
00097 
00098 bool PsnCoherantMemoryManager::lockNeeded() {
00099    assert (_memoryElementDescriptorMemoryManager == this ) ;
00100    return true; 
00101 }
00102 
00103 
00104 void PsnCoherantMemoryManager::sync() {
00105    //nothing to do : the memory is assumed to behave whith a strong coherance
00106 }
00107 
00108 
00109 void PsnCoherantMemoryManager::synchronizeAfterLock(void* beginningAdress, long length) {
00110    //nothing to do : the memory is assumed to behave whith a strong coherance
00111 }
00112 
00113 
00114 PsnMemoryElementDescriptor * PsnCoherantMemoryManager::getFreeMem() {
00115    assert(_locked|| !lockNeeded() );
00116    return (PsnMemoryElementDescriptor *)localAddressToGlobal(*((unsigned int *)_startDsm));
00117 }
00118 
00119 void PsnCoherantMemoryManager::setFreeMem(PsnMemoryElementDescriptor * ptr) {
00120    assert(_locked|| !lockNeeded() );
00121    *((unsigned int *)_startDsm)=globalAddressToLocal(ptr);
00122 }
00123 
00124 
00125 void *PsnCoherantMemoryManager::getFromFree(size_t size) {
00126 
00127    assert( _locked || ! lockNeeded () );
00128 
00129    PsnMemoryElementDescriptor *i , *pred ;
00130 #ifdef _DEBUGALLOCATIONMOME
00131    cerr<<MomeInternalDate()<<" PsnCoherantMemoryManager::getFromFree "<<size<<" ";
00132 #endif
00133    unsigned int addr ;
00134    i = getFreeMem() ;
00135    pred = NULL ;
00136    addr = 0 ;
00137    
00138   while ( i != NULL )
00139     {
00140 #ifdef _DEBUGALLOCATIONMOME
00141        cerr<<"."<<globalAddressToLocal(i)<<" "<<i->base<<" "<<i->size<<" "<<i->next<<endl;
00142 #endif
00143        if ( (i->size >= size) )   /* First fit strategy  && (i->size!=12) */
00144           {
00145              addr = i->base ;
00146              assert(addr % 2 != 1) ;
00147              if ( i->size == size )
00148                 {
00149                    if ( pred == NULL ) {
00150                       setFreeMem( (PsnMemoryElementDescriptor *)localAddressToGlobal(getFreeMem()->next)) ;
00151                    }
00152                    else {
00153                       pred->next = i->next ;
00154                    }
00155                    if ( i != localAddressToGlobal(i->base) ) {
00156                       delete ( i ) ;
00157                    }
00158                    i = NULL ;
00159                 }
00160              else
00161                 {
00162                    if (i->base == globalAddressToLocal(i) ) {
00163                       //we are trying to allocate part of the block containing the data of the block :
00164                       if (i->size < size + sizeof(PsnMemoryElementDescriptor) ) 
00165                          {  //allocation is impossible without moving the memoryElementDescriptor
00166                             pred = i ;
00167                             i = (PsnMemoryElementDescriptor *)localAddressToGlobal(i->next) ;   
00168                          }      
00169                       else {
00170                          addr = i->base + i->size - size ;
00171                          //allocate at the end of the free zone
00172                          i->size = i->size - size ;
00173                          i = NULL ;
00174                       }                  
00175                    }
00176                    else {
00177                       i->base = i->base + size ;
00178                       i->size = i->size - size ;
00179                       i = NULL ;
00180                    }
00181                 }
00182           }
00183        else
00184           {
00185              pred = i ;
00186              i = (PsnMemoryElementDescriptor *)localAddressToGlobal(i->next) ;
00187           }
00188     }
00189 #ifdef _DEBUGALLOCATIONMOME
00190   cerr<<" "<<localAddressToGlobal(addr)<<"("<<addr<<")"<<endl;
00191   assert(addr %2 != 1) ;
00192 #endif
00193   return localAddressToGlobal(addr) ;
00194 }
00195 #include <unistd.h>
00196 
00197 void PsnCoherantMemoryManager::addInFree ( void *addr, size_t size) {
00198 
00199    assert( _locked || ! lockNeeded () );
00200 
00201    PsnMemoryElementDescriptor *l, *iNew, *tmpPtr, *tmpPtr1, *tmpPtr2;
00202 #ifdef _DEBUGALLOCATIONMOME
00203    cerr<<MomeInternalDate()<<" PsnCoherantMemoryManager::"<<this<<"::addInFree "<<addr<<"("<<globalAddressToLocal(addr)<<") "<<size<<endl;
00204 #endif
00205    unsigned int _addr,temp;
00206    /* il ne faut pas faire de delete avant que le mémoire ne soir dans un état cohérant, donc on suavegarde ce qu'il faudra éventuellement détruire */
00207    tmpPtr1=NULL;
00208    tmpPtr2=NULL;
00209 
00210    _addr=globalAddressToLocal(addr);
00211 
00212    if ( size == sizeof (PsnMemoryElementDescriptor) ) {
00213       iNew = new(addr) PsnMemoryElementDescriptor () ;
00214       iNew->next = 0;
00215       assert (_addr != iNew->base) ;
00216    }
00217    else {
00218       iNew = new(this) PsnMemoryElementDescriptor ();
00219    }
00220    assert (_addr % 2 != 1 ) ;
00221    iNew->base = _addr ;
00222    iNew->size = size;
00223 
00224    if ( getFreeMem() == NULL )    /* Empty list */
00225       {
00226          iNew->next = getAnInvalidOffset();
00227          setFreeMem(iNew) ;
00228       }
00229    else
00230       {
00231          l = getFreeMem() ;   
00232          if ( l->base > _addr )
00233             {                   /* iNew is the lowest interval */
00234                iNew->next = globalAddressToLocal(getFreeMem()) ;
00235                setFreeMem(iNew) ;
00236                l = iNew ;
00237             }
00238          else
00239             { /* Search the immediate lower interval */
00240                tmpPtr=(PsnMemoryElementDescriptor *) localAddressToGlobal(l->next);
00241                while ( ( ! invalidOffset(l->next) ) && 
00242                        ( _addr > tmpPtr->base ) ) {
00243                   
00244                   l = tmpPtr;
00245                   tmpPtr=(PsnMemoryElementDescriptor *) localAddressToGlobal(l->next) ;           
00246                }
00247                /* the new free zone (iNew) is between l and l->next */
00248                iNew->next = l->next ;
00249                l->next = globalAddressToLocal(iNew) ;
00250                
00251                if ( ( !invalidOffset(iNew->next) ) &&
00252                     ( iNew->base + iNew->size == ((PsnMemoryElementDescriptor *) localAddressToGlobal(iNew->next))->base ) ) 
00253                   { /* no memory is allocated between iNew and iNew->next */
00254                      tmpPtr1 = (PsnMemoryElementDescriptor *) localAddressToGlobal(iNew->next) ;
00255                      iNew->size = iNew->size + tmpPtr1->size ;
00256                      iNew->next = tmpPtr1->next ;
00257                   }
00258             }
00259          
00260          if ( l->base + l->size == ((PsnMemoryElementDescriptor *) localAddressToGlobal(l->next))->base )
00261             { /* no memory is allocated between l and l->next */
00262                tmpPtr2 = (PsnMemoryElementDescriptor *)localAddressToGlobal(l->next) ;
00263                l->size = l->size + tmpPtr2->size ;
00264                l->next = tmpPtr2->next ;
00265                if ( tmpPtr2 != localAddressToGlobal(tmpPtr2->base) ) {
00266                   delete tmpPtr2 ;
00267                }
00268             }
00269       }
00270    if (tmpPtr1!=NULL) {
00271       if (tmpPtr1 != localAddressToGlobal(tmpPtr1->base) ) {
00272          delete tmpPtr1 ;
00273       }
00274    }
00275 #ifdef _DEBUGALLOCATIONMOME
00276    cerr<<"PsnCoherantMemoryManager::"<<this<<"::addInFree fait"<<endl;
00277 #endif
00278 }
00279 
00280 #endif

logo OpenMask

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

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