QCMemory.cpp

Go to the documentation of this file.
00001 //*****************************************************************************//
00002 //                                                                             //
00003 //   Copyright (c) 2001                                                        //
00004 //      INRIA                                                                  //
00005 //      54600 VILLERS LES NANCY                                                //
00006 //      France                                                                 //
00007 //                                                                             //
00008 //*****************************************************************************//
00009 //                                                                             //
00010 //               *** NOTICE OF PROPRIETARY INFORMATION ***                     //
00011 //                                                                             //
00012 // The information contained in this file is considered proprietary and the    //
00013 // exclusive property of  INRIA. This information may not be disclosed,        //
00014 // duplicated or used, in whole or in part, for  any purpose  whatsoever       //
00015 // without express written authorization from INRIA                            //
00016 //                                                                             //
00017 //*****************************************************************************//
00018 #include <string>
00019 
00020 #include "QCCommon.hpp"
00021 #include "QCMemory.hpp"
00022 #include "QCErrorManager.hpp"
00023 #include "QCMDSystem.hpp"
00024 
00025 
00029 QCMemory::QCMemory (void) : curTmpMem(0), maxTmpMem(0), blockTmpMem(NULL), freeMemPtr(NULL),
00030                             endOfBlock(NULL), blockSize(0), stackPtr(NULL), stackPtrIndex(0), stackPtrMaxIndex (0) 
00031 {}
00032 
00036 QCMemory::~QCMemory     (void) {
00037   
00038   disallocateBlockTmpMem();
00039 }
00040 
00041 
00042 
00043 
00047 template <class TP>
00048 TP*     
00049 QCMemory::takeTmpMem (const int& nb) {
00050   
00051   int stackPtrIncrement = 10;
00052   TP* tmpMemPtr         = NULL;
00053   QCStackCell* tmpPtr;
00054   
00060   int requestedMemSize = (sizeof(TP) * nb - 1) / sizeof(QCFloat) + 1;
00061 
00062   // Mise a jour de curTmpMem.
00063   curTmpMem += requestedMemSize;
00064   
00065   // Mise a jour de maxTmpMem.
00066   if (curTmpMem > maxTmpMem) {
00067     maxTmpMem = curTmpMem;
00068   }
00069   
00070   /******************************************************
00071    * Si on a deja alloue un bloc de memoire temporaire, *
00072    * on s en sert.                                      *
00073    ******************************************************/
00074   if (blockTmpMem) {
00075   
00080     if ( (endOfBlock - freeMemPtr) >= requestedMemSize) {
00081       tmpMemPtr = reinterpret_cast<TP*>(freeMemPtr);
00082       //On stocke le pointeur dans une pile.
00083       freeMemPtr += requestedMemSize;
00084     }
00085   }
00086   /*****************************
00087    * sinon allocation de base. *
00088    *****************************/
00089   if (!tmpMemPtr) {
00090     tmpMemPtr = new TP[nb];
00091 
00092 #ifdef TRACE_QC_MEMORY
00093     cout << "  >>>>WARNING  CQCMemory::takeTmpMem (" << nb <<")" 
00094          <<" allocate by new <<<<<<<<<<" << endl ;
00095 #endif
00096   }
00097   /****************************************************************
00098    * Si la pile de stockage des pointeurs n est pas assez grande, *
00099    * il faut augmenter sa taille.                                 *
00100    ****************************************************************/
00101   
00102   if (stackPtrIndex == stackPtrMaxIndex) {
00103     stackPtrMaxIndex += stackPtrIncrement;
00104     tmpPtr            = new QCStackCell[stackPtrMaxIndex];
00105     if (stackPtr) { 
00106       memcpy(tmpPtr, stackPtr, stackPtrIndex*sizeof(QCStackCell) ); 
00107       delete [] stackPtr; 
00108     }
00109     stackPtr = tmpPtr;
00110   }
00111 
00112   // On stocke dans la pile des pointeurs.
00113   stackPtr[stackPtrIndex].memPtr  = reinterpret_cast<QCFloat*>(tmpMemPtr);
00114   stackPtr[stackPtrIndex].memSize = requestedMemSize;
00115   stackPtrIndex++;
00116 #ifdef TRACE_QC_MEMORY
00117   cout << "take de tmpMemPtr = " << tmpMemPtr 
00118        << " car requestedMemSize = " << requestedMemSize  << endl ;
00119 #endif //TRACE_CQCMemory
00120 
00121   return tmpMemPtr;
00122 }
00123 
00124 
00125 
00129 template <class TP>
00130 bool    
00131 QCMemory::giveBackTmpMem (TP* QCRestrict & tmpMemPtr) {
00132   
00133   bool desallocDone = false;
00134   bool retVal = true;
00139   QCFloat* tmpMemPtrInQCFloat = (QCFloat*)(tmpMemPtr);
00145 #ifdef TRACE_QC_MEMORY
00146   cout << " QCMEMORY::giveBack de tmpMemPtr : " << tmpMemPtrInQCFloat << endl;
00147 #endif //TRACE_CQCMemory 
00148   
00149   // On verifie que l on desalloue le bon pointeur 
00150   --stackPtrIndex;
00151   if (tmpMemPtrInQCFloat == stackPtr[stackPtrIndex].memPtr){ 
00152 
00153     // Mise a jour de curTmpMem
00154     curTmpMem -= stackPtr[stackPtrIndex].memSize;
00159     if (blockTmpMem) {
00160       
00161       // On verifie que le pointeur que l on desalloue appartient
00162       // au bloc
00163       if ( (tmpMemPtrInQCFloat >= blockTmpMem) && 
00164            (tmpMemPtrInQCFloat < endOfBlock) ) {
00165         freeMemPtr -= stackPtr[stackPtrIndex].memSize;
00166         desallocDone = true;
00167       }
00168     }
00169     
00170     // Sinon desalloc de base.
00171     if (!desallocDone) {
00172       if (tmpMemPtr) { delete [] tmpMemPtr ; }
00173     }
00174     
00179     tmpMemPtr = NULL;
00180   
00181   } else {
00182    
00183     cout << endl << endl 
00184          << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<< endl 
00185          << " >>>>> WRONG ORDER TO GIVE BACK TEMPORY MEMORY <<<<<<"<< endl  
00186          << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<< endl 
00187          << endl << endl ;
00192     QCErrorManager   errorManager;
00193     retVal = false;
00194     
00195     // Attention, la liste d arguments est variable.
00196     errorManager.writeMsg(QCErrorManager::ERROR,
00197                           const_cast<char*>(QCErrorManager::TMP_MEMORY) );
00198   }
00199 #ifdef TRACE_QC_MEMORY
00200   cout << " " << (QCFloat*)(tmpMemPtr) << endl;
00201 #endif //TRACE_CQCMemory 
00202 
00203   return retVal;
00204 }
00205 
00206 
00207 
00208 
00212 bool 
00213 QCMemory::updateBlockTmpMem (void) {
00214   
00215   bool retVal = true;
00216   /***********************************************************************
00217    * Pour allouer le bloc, il faut obligatoirement ne pas avoir de blocs *
00218    * temporaires alloues; sinon, on ne peut desallouer le blockTmpMem.   *
00219    ***********************************************************************/
00220   
00221   if (curTmpMem == 0) {
00222   
00223     // Si on a un max superieur a la memoire allouee dans le bloc.
00224     if (maxTmpMem > blockSize) {
00225       
00226       if (blockTmpMem) { delete [] blockTmpMem; }
00227       
00228       // On alloue un nouveau bloc.
00229       blockSize   = maxTmpMem;
00230       blockTmpMem = new QCFloat[blockSize];
00231       retVal      = (blockTmpMem) ? true : false;
00232       freeMemPtr  =  blockTmpMem;
00233       endOfBlock  =  blockTmpMem + blockSize;
00234 #ifdef TRACE_QC_MEMORY
00235       cout << "Allocation du block " << blockTmpMem << " de taille = " 
00236            << blockSize 
00237            << " dans updateBlockTmpMem " << endl;
00238       cout << "Fin du block en " << endOfBlock << endl;
00239 #endif //TRACE_QC_Memory
00240     }
00241   }
00242 
00243   if (!retVal) {
00248     QCErrorManager  errorManager;   
00249     
00250     //Attention, la liste d arguments est variable.
00251     errorManager.writeMsg(QCErrorManager::ERROR,
00252                           const_cast<char*>(QCErrorManager::BAD_ALLOC) );
00253   }
00254   
00255   return retVal;
00256 }
00257 
00258 
00259 
00263 void
00264 QCMemory::disallocateBlockTmpMem (void) {
00265 
00266   if (blockTmpMem) {
00267     delete [] blockTmpMem;
00268     blockTmpMem = NULL;
00269   }
00270 
00271   // Plus besoin non plus de la stackPtr.
00272   if (stackPtr) {
00273     delete [] stackPtr;
00274     stackPtr = NULL;
00279     if (maxTmpMem >  blockSize) {
00287       QCErrorManager  errorManager;
00288 
00289       //Attention, la liste d'arguments est variable.
00290       errorManager.writeMsg(QCErrorManager::WARNING,
00291                             const_cast<char*>(QCErrorManager::UNOPTIMAL_TMP_MEM)); 
00292     }
00293   }
00294 }
00295 
00296 
00297 
00298 
00302 void
00303 QCMemory::evaluateUsedMemory (void) {
00304   
00305 #ifndef __CYGWIN__
00306   char str[256];
00307   sprintf(str, "ps -p%d -o vsz  | tail -1 >> %s", 
00308   QCCommon::Pid, QCCommon::MemoryTmpFile.c_str() );
00309   system(str);
00310 #else
00311   cout << "QCMemory::evaluateUsedMemory not available on this architecture."
00312        << endl;
00313 #endif
00314 }
00315 
00316 
00317 
00318 
00322 QCFloat
00323 QCMemory::getUsedMemoryMax (void) {
00324   char          lineIn[QCCStrLen_32];
00325   FILE*         memoryStream = NULL;
00326   int           dynAllocMem = 0;
00327   int           dynAllocMemMax = 0;
00328   std::string   fileName ;
00329   fileName = QCCommon::outdir+PATH_SEPARATOR+QCCommon::MemoryTmpFile ;
00330 
00331   if ( (memoryStream = fopen(fileName.c_str(), "r") ) ) {
00332     while (fgets(lineIn, QCCStrLen_32, memoryStream) ) {
00333       sscanf(lineIn, "%d", &dynAllocMem);
00334       if (dynAllocMem > dynAllocMemMax) {
00335         dynAllocMemMax = dynAllocMem;
00336       }
00337     }
00338     fclose(memoryStream);
00339   }
00340 #ifndef __QC_cxx__
00341   //Attention, 1 Mo == 1024 Ko.
00342   return dynAllocMemMax/QC1024;
00343 #else //__QC_cxx__
00344   return dynAllocMemMax;
00345 #endif //__QC_cxx__
00346 }
00347 
00348 
00349 
00350 
00354 void
00355 QCMemory::printUsedMemoryMax (void) {
00356   //printf("%s : \t%10.3f MB\n", QCWriter::UsedMemoryMaxCStr, getUsedMemoryMax() );
00357 }
00358 
00359 
00360 
00364 void   
00365 QCMemory::printQCMemory (void){
00366 
00367   cout << "QCMemory  :   ----------------------------------------------------------------------- "
00368        << endl
00369        << "   curTmpMem         : " << curTmpMem
00370        << "     maxTmpMem  : "      << maxTmpMem<<std::endl 
00371        << "   blockTmpMem       : " << blockTmpMem
00372        << endl 
00373        << "   freeMemPtr        : " << freeMemPtr        
00374        << "    endOfBlock : "       << endOfBlock
00375        <<"  Space : "               << (endOfBlock-freeMemPtr) 
00376        << endl 
00377        << "   blockSize         : " << blockSize         
00378        << endl  ;
00379   if ( stackPtr != NULL) {   
00380     cout << "   Size of the stack : "    << stackPtr->memSize 
00381          << endl 
00382          << "   stackPtr_>memPtr  : "    << stackPtr->memPtr  
00383          << endl 
00384          << "   stackPtrIndex     : "    << stackPtrIndex     
00385          << "        stackPtrMaxIndex "  << stackPtrMaxIndex 
00386          << endl ;
00387     cout << "    " ;
00388     for(int i= 0 ; i< stackPtrIndex ; ++i )
00389       {
00390         cout << " ( " << i << " , "
00391              << stackPtr[i].memPtr << " )  " ;
00392       }
00393     cout << endl ;
00394   
00395   } else {
00396     cout  << "   Size of the stack :  0     " << endl 
00397           << "   stackPtr_>memPtr  :  (nil) " << endl ;
00398   }
00399   cout << "End of QCMemory ----------------------------------------------------------------------"
00400        << endl ;
00401 
00402 }
00403 
00404 
00405 
00406 
00410 bool 
00411 QCMemory::setUsedMemoryMax (const int size){
00412 
00413   maxTmpMem  = size ;
00414   cout << "QCMemory::setUsedMemoryMax : TO IMPROOVE "<< endl;
00415   bool retVal = false ;
00416   //
00417   retVal = updateBlockTmpMem() ;  
00418   //
00419   printQCMemory () ;
00420   cout << "End of QCMemory::setUsedMemoryMax ==========================="
00421        << endl;
00422   return retVal ;
00423 }
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00436 template int*      
00437 QCMemory::takeTmpMem<int>(const int& nb);
00438 
00439 template QCFloat*  
00440 QCMemory::takeTmpMem<QCFloat>(const int& nb);
00441 
00442 template QCFloat** 
00443 QCMemory::takeTmpMem<QCFloat*>(const int& nb);
00444 
00445 template QCTopEnergyLevel*  
00446 QCMemory::takeTmpMem<QCTopEnergyLevel>(const int& nb);
00447 
00448 template bool*     
00449 QCMemory::takeTmpMem<bool>(const int& nb);
00450 
00451 template char*     
00452 QCMemory::takeTmpMem<char>(const int& nb);
00453 
00454 template bool      
00455 QCMemory::giveBackTmpMem<int>(int* QCRestrict & tmpMemPtr);
00456 
00457 template bool      
00458 QCMemory::giveBackTmpMem<QCFloat>(QCFloat* QCRestrict & tmpMemPtr);
00459 
00460 template bool      
00461 QCMemory::giveBackTmpMem<QCFloat* QCRestrict>(QCFloat* QCRestrict * QCRestrict & tmpMemPtr);
00462 
00463 template bool      
00464 QCMemory::giveBackTmpMem<QCTopEnergyLevel>(QCTopEnergyLevel* QCRestrict & tmpMemPtr);
00465 
00466 template bool      
00467 QCMemory::giveBackTmpMem<bool>(bool* QCRestrict & tmpMemPtr);
00468 
00469 template bool 
00470 QCMemory::giveBackTmpMem<char>(char* QCRestrict & tmpMemPtr);

Generated on Sat Jan 28 21:07:28 2006 for QC++ by  doxygen 1.4.4