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
| Documentation generated on Mon Nov 25 15:25:00 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |