00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00063 curTmpMem += requestedMemSize;
00064
00065
00066 if (curTmpMem > maxTmpMem) {
00067 maxTmpMem = curTmpMem;
00068 }
00069
00070
00071
00072
00073
00074 if (blockTmpMem) {
00075
00080 if ( (endOfBlock - freeMemPtr) >= requestedMemSize) {
00081 tmpMemPtr = reinterpret_cast<TP*>(freeMemPtr);
00082
00083 freeMemPtr += requestedMemSize;
00084 }
00085 }
00086
00087
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
00099
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
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
00150 --stackPtrIndex;
00151 if (tmpMemPtrInQCFloat == stackPtr[stackPtrIndex].memPtr){
00152
00153
00154 curTmpMem -= stackPtr[stackPtrIndex].memSize;
00159 if (blockTmpMem) {
00160
00161
00162
00163 if ( (tmpMemPtrInQCFloat >= blockTmpMem) &&
00164 (tmpMemPtrInQCFloat < endOfBlock) ) {
00165 freeMemPtr -= stackPtr[stackPtrIndex].memSize;
00166 desallocDone = true;
00167 }
00168 }
00169
00170
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
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
00218
00219
00220
00221 if (curTmpMem == 0) {
00222
00223
00224 if (maxTmpMem > blockSize) {
00225
00226 if (blockTmpMem) { delete [] blockTmpMem; }
00227
00228
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
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
00272 if (stackPtr) {
00273 delete [] stackPtr;
00274 stackPtr = NULL;
00279 if (maxTmpMem > blockSize) {
00287 QCErrorManager errorManager;
00288
00289
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
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
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);