TMemStatManager.cxx

Go to the documentation of this file.
00001 // @(#)root/new:$Name$:$Id: TMemStatManager.cxx 29415 2009-07-09 15:51:24Z rdm $
00002 // Author: D.Bertini and M.Ivanov   10/08/2000  -- Anar Manafov (A.Manafov@gsi.de) 28/04/2008
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //****************************************************************************//
00013 /*
00014  TMemStatManager - manager class
00015 
00016  The current memory statistic is written to the file
00017 
00018  Important information  used for visualization
00019  std::vector<TMemStatStackInfo>       fStackVector;    // vector with stack symbols
00020  std::vector<TMemStatInfoStamp>       fStampVector;    // vector of stamp information
00021  std::vector<TTimeStamp>       fStampTime;      // vector of stamp information
00022  std::vector<TMemStatCodeInfo>        fCodeInfoArray;  // vector with code info
00023 */
00024 //****************************************************************************//
00025 
00026 // STD
00027 #include <cstdio>
00028 #include <string>
00029 
00030 // ROOT
00031 #include "TSystem.h"
00032 #include "TEnv.h"
00033 #include "TError.h"
00034 #include "Riostream.h"
00035 #include "TObject.h"
00036 #include "TFile.h"
00037 #include "TTree.h"
00038 #include "TObjString.h"
00039 // Memstat
00040 #include "TMemStatDepend.h"
00041 #include "TMemStatInfo.h"
00042 #include "TMemStatManager.h"
00043 
00044 const char * const g_cszFileName("memstat.root");
00045 const Int_t g_STHashSize(65536);   //!current size of the hash table
00046 
00047 ClassImp(TMemStatManager)
00048 
00049 TMemStatManager * TMemStatManager::fgInstance = NULL;
00050 
00051 
00052 //****************************************************************************//
00053 //                                   Global Stack Table
00054 //****************************************************************************//
00055 
00056 TMemStatManager::TMemStatManager():
00057       TObject(),
00058       fSTHashTable(g_STHashSize, -1),           //!pointer to the hash table
00059       fCount(0),                 //!number of entries in table
00060       fStampNumber(0),           //current stamp number
00061       fStackVector(),            // vector with stack symbols
00062       fStampVector(),            // vector of stamp information
00063       fStampTime(),              // vector of stamp information
00064       fCodeInfoArray()        ,  // vector with code info
00065       fCodeInfoMap(),            //! map of code information
00066       fDebugLevel(0),            //!debug level
00067       fStampCallBack(0),         //! call back function to register stamp
00068       fPreviousMallocHook(TMemStatDepend::GetMallocHook()),    //!
00069       fPreviousFreeHook(TMemStatDepend::GetFreeHook()),      //!
00070       fLastStamp(),              //last written stamp
00071       fCurrentStamp(),           //current stamp
00072       fAutoStampSize(2000000),   //change of size invoking STAMP
00073       fAutoStampN(200000),       //change of number of allocation  STAMP
00074       fAutoStampDumpSize(50000), //change of number of allocation  STAMP
00075       fMinStampSize(100),        //minimal cut what will be dumped  to the tree
00076       fSize(65536),              //!size of hash table
00077       fLeak(NULL),               //!pointer to the hash table
00078       fAllocCount(0),            //!number of memory allocation blocks
00079       fMultDeleteTable(),        //!pointer to the table
00080       fDumpTree(0),              //!tree to dump information
00081       fDumpSysTree(0),           //!tree to dump information
00082       fUseGNUBuildinBacktrace(kFALSE)
00083 {
00084    // Default constructor
00085 
00086    SetBit(kUserDisable, kTRUE);
00087    fStampCallBack = TMemStatManager::SAddStamps;         //! call back function
00088 
00089 }
00090 
00091 //______________________________________________________________________________
00092 void TMemStatManager::Init()
00093 {
00094    //Initialize MemStat manager - used only for instance
00095 
00096    SetBit(kUserDisable, kTRUE);
00097 
00098    fStampNumber = 0;
00099    fAllocCount = 0;
00100    FreeHashtable();
00101    fLeak = (TMemTable_t **) malloc(sizeof(void *) * fSize);
00102    fMultDeleteTable.fLeaks = 0;
00103    fMultDeleteTable.fAllocCount = 0;
00104    fMultDeleteTable.fTableSize = 0;
00105    fStackVector.reserve(fSize);             // vector with stack symbols
00106    fStampVector.reserve(fSize*10);          // vector of stamp information
00107    fCodeInfoArray.reserve(fSize);           // vector with code info
00108    fStampTime.reserve(fSize);
00109    fStampTime[0] = TTimeStamp();
00110    for (int i = 0; i < fSize; ++i) {
00111       fLeak[i] = (TMemTable_t *) malloc(sizeof(TMemTable_t));
00112       fLeak[i]->fAllocCount = 0;
00113       fLeak[i]->fMemSize = 0;
00114       fLeak[i]->fFirstFreeSpot = 0;
00115       fLeak[i]->fTableSize = 0;
00116       fLeak[i]->fLeaks = 0;
00117    }
00118    //Initialize ST table.
00119    fCount = 0;
00120 
00121    SetBit(kUserDisable, kTRUE);
00122 }
00123 
00124 //______________________________________________________________________________
00125 TMemStatManager* TMemStatManager::GetInstance()
00126 {
00127    // GetInstance of MemStatManager
00128    // Only instance catch the alloc and free hook
00129 
00130    if (!fgInstance) {
00131       fgInstance = new TMemStatManager;
00132       fgInstance->Init();
00133    }
00134    return fgInstance;
00135 }
00136 
00137 //______________________________________________________________________________
00138 void TMemStatManager::Close()
00139 {
00140    // to be documented
00141 
00142    delete fgInstance;
00143    fgInstance = NULL;
00144 }
00145 
00146 //______________________________________________________________________________
00147 TMemStatManager::~TMemStatManager()
00148 {
00149    //   Destructor
00150    //   if instance is destructed - the hooks are reseted to old hooks
00151 
00152    if (this != TMemStatManager::GetInstance())
00153       return;
00154    SetBit(kStatDisable);
00155    Disable();
00156    AddStamps("End");
00157    DumpTo(kTree, kTRUE, "End");
00158    DumpTo(kSysTree, kTRUE, "End");
00159    Disable();
00160 
00161    FreeHashtable();
00162 }
00163 
00164 //______________________________________________________________________________
00165 void TMemStatManager::Enable()
00166 {
00167    // Enable hooks
00168 
00169    if (this != GetInstance())
00170       return;
00171 
00172    // set hook to our functions
00173    TMemStatDepend::SetMallocHook(AllocHook);
00174    TMemStatDepend::SetFreeHook(FreeHook);
00175    SetBit(kUserDisable, kFALSE);
00176 }
00177 
00178 //______________________________________________________________________________
00179 void TMemStatManager::Disable()
00180 {
00181    // disble MemStatManager
00182 
00183    if (this != GetInstance())
00184       return;
00185 
00186    // set hook to our functions
00187    TMemStatDepend::SetMallocHook(fPreviousMallocHook);
00188    TMemStatDepend::SetFreeHook(fPreviousFreeHook);
00189    SetBit(kUserDisable, kTRUE);
00190 }
00191 
00192 //______________________________________________________________________________
00193 void *TMemStatManager::AllocHook(size_t size, const void* /*caller*/)
00194 {
00195    // AllocHook
00196 
00197    TMemStatManager* instance = TMemStatManager::GetInstance();
00198    TMemStatDepend::SetMallocHook(instance->fPreviousMallocHook);
00199    void *p = instance->AddPointer(size);
00200    TMemStatDepend::SetMallocHook(AllocHook);
00201    return p;
00202 }
00203 
00204 //______________________________________________________________________________
00205 void TMemStatManager::FreeHook(void* ptr, const void* /*caller*/)
00206 {
00207    // FreeHook
00208 
00209    TMemStatManager* instance = TMemStatManager::GetInstance();
00210    TMemStatDepend::SetFreeHook(instance->fPreviousFreeHook);
00211    instance->FreePointer(ptr);
00212    TMemStatDepend::SetFreeHook(FreeHook);
00213 }
00214 
00215 //______________________________________________________________________________
00216 TMemStatStackInfo *TMemStatManager::STAddInfo(int size, void **stackptrs)
00217 {
00218    // Add stack information to table.
00219    // add next stack to table
00220 
00221    const UInt_t currentSize = fStackVector.size();
00222    if (currentSize >= fStackVector.capacity())
00223       fStackVector.reserve(2*currentSize + 1);
00224 
00225    fStackVector.push_back(TMemStatStackInfo());
00226    TMemStatStackInfo *info = &(fStackVector[currentSize]);
00227    info->Init(size, stackptrs, this, currentSize);
00228    info->fStackID = currentSize;
00229 
00230    //add info to hash table
00231    const int hash = int(info->Hash() % g_STHashSize);
00232    Int_t hashIndex = fSTHashTable[hash];
00233    TMemStatStackInfo *info2 = NULL;
00234 
00235    if (-1 == hashIndex) {
00236       fSTHashTable[hash] = info->fStackID;
00237    } else {
00238       info2 = &fStackVector[hashIndex];
00239       while (hashIndex >= 0) {
00240          hashIndex = info2->fNextHash;
00241          if (hashIndex >= 0)
00242             info2 = &fStackVector[hashIndex];
00243       }
00244       info2->fNextHash = info->fStackID;
00245    }
00246 
00247    ++fCount;
00248    fStackVector.push_back(*info);
00249    return info;
00250 }
00251 
00252 //______________________________________________________________________________
00253 TMemStatStackInfo *TMemStatManager::STFindInfo(int size, void **stackptrs)
00254 {
00255    // Try to find stack info in hash table if doesn't find it will add it.
00256 
00257    const int hash = int(TMemStatStackInfo::HashStack(size, (void **)stackptrs) % g_STHashSize);
00258 
00259    if (fSTHashTable[hash] < 0)
00260       return STAddInfo(size, stackptrs); // hash value not in hash table
00261 
00262    Int_t hashIndex = fSTHashTable[hash];
00263    TMemStatStackInfo *info = NULL;
00264 
00265    info = &fStackVector[hashIndex];
00266    while (hashIndex >= 0) {
00267       if (info->Equal(size, stackptrs) == 1)
00268          return info;   // info found
00269       hashIndex = info->fNextHash;
00270       if (hashIndex >= 0)
00271          info = &fStackVector[hashIndex];
00272    }
00273    return STAddInfo(size, stackptrs);  // not found info - create new
00274 }
00275 
00276 //______________________________________________________________________________
00277 void TMemStatManager::SAddStamps(const char * stampname)
00278 {
00279    //
00280    // static version add  stamps to the list of stamps for changed stacks
00281    //
00282    TMemStatManager *man = GetInstance();
00283    man->AddStamps(stampname);
00284 }
00285 
00286 //______________________________________________________________________________
00287 void  TMemStatManager::AddStamps(const char * stampname)
00288 {
00289    // add the stamp to the list of stamps
00290 
00291    const UInt_t ssize = fStackVector.size();
00292    for (UInt_t i = 0; i < ssize; ++i) {
00293       if (fStackVector[i].fCurrentStamp.fAllocSize > fMinStampSize)
00294          fStackVector[i].MakeStamp(fStampNumber);
00295    }
00296    const UInt_t csize = fCodeInfoArray.size();
00297    for (UInt_t i = 0; i < csize; ++i) {
00298       if (fCodeInfoArray[i].fCurrentStamp.fAllocSize > fMinStampSize)
00299          fCodeInfoArray[i].MakeStamp(fStampNumber);
00300    }
00301 
00302    fCurrentStamp.fID = -1;
00303    fCurrentStamp.fStampNumber = fStampNumber;
00304    AddStamp() = fCurrentStamp;
00305 
00306    fStampTime[fStampNumber] = TTimeStamp();
00307    if (fStampVector.size() >= fAutoStampDumpSize || stampname) {
00308       DumpTo(kTree, kTRUE, stampname);
00309       DumpTo(kSysTree, kTRUE, stampname);
00310    }
00311    ++fStampNumber;
00312 }
00313 
00314 //______________________________________________________________________________
00315 TMemStatInfoStamp &TMemStatManager::AddStamp()
00316 {
00317    // add one stamp to the list of stamps
00318 
00319    const UInt_t size = fStampVector.size();
00320    fStampVector.push_back(TMemStatInfoStamp());
00321    TMemStatInfoStamp &stamp =  fStampVector[size];
00322    stamp.fStampNumber = fStampNumber;
00323    return stamp;
00324 }
00325 
00326 //______________________________________________________________________________
00327 TMemStatCodeInfo &TMemStatManager::GetCodeInfo(void *address)
00328 {
00329    //  to be documented
00330 
00331    TMemStatCodeInfo *info(NULL);
00332    const UInt_t index = fCodeInfoMap[address];
00333    if (index > 0) {
00334       info = &(fCodeInfoArray[fCodeInfoMap[address]]);
00335    } else {
00336       const UInt_t size = fCodeInfoArray.size();
00337       fCodeInfoArray.push_back(TMemStatCodeInfo());
00338       info = &(fCodeInfoArray[size]);
00339       fCodeInfoMap[address] = size;
00340       info->fCodeID = size;
00341       info->fCurrentStamp.fID = info->fCodeID;
00342       info->fLastStamp.fID = info->fCodeID;
00343    }
00344    return *info;
00345 }
00346 
00347 //______________________________________________________________________________
00348 void TMemStatManager::RehashLeak(int newSize)
00349 {
00350    // Rehash leak pointers.
00351 
00352    if (newSize <= fSize)
00353       return;
00354    TMemTable_t **newLeak = (TMemTable_t **) malloc(sizeof(void *) * newSize);
00355    for (int i = 0; i < newSize; ++i) {
00356       //build new branches
00357       newLeak[i] = (TMemTable_t *) malloc(sizeof(TMemTable_t));
00358       newLeak[i]->fAllocCount = 0;
00359       newLeak[i]->fMemSize = 0;
00360       newLeak[i]->fFirstFreeSpot = 0;
00361       newLeak[i]->fTableSize = 0;
00362       newLeak[i]->fLeaks = 0;
00363    }
00364    for (int ib = 0; ib < fSize; ++ib) {
00365       TMemTable_t *branch = fLeak[ib];
00366       for (int i = 0; i < branch->fTableSize; i++)
00367          if (branch->fLeaks[i].fAddress != 0) {
00368             int hash = int(TString::Hash(&branch->fLeaks[i].fAddress, sizeof(void*)) % newSize);
00369             TMemTable_t *newbranch = newLeak[hash];
00370             if (newbranch->fAllocCount >= newbranch->fTableSize) {
00371                int newTableSize =
00372                   newbranch->fTableSize ==
00373                   0 ? 16 : newbranch->fTableSize * 2;
00374                newbranch->fLeaks =
00375                   (TMemInfo_t *) realloc(newbranch->fLeaks,
00376                                          sizeof(TMemInfo_t) * newTableSize);
00377                if (!newbranch->fLeaks) {
00378                   Error("TMemStatManager::AddPointer", "realloc failure");
00379                   _exit(1);
00380                }
00381                memset(newbranch->fLeaks + newbranch->fTableSize, 0,
00382                       sizeof(TMemInfo_t) * (newTableSize -
00383                                             newbranch->fTableSize));
00384                newbranch->fTableSize = newTableSize;
00385             }
00386             memcpy(&newbranch->fLeaks[newbranch->fAllocCount],
00387                    &branch->fLeaks[i], sizeof(TMemInfo_t));
00388             newbranch->fAllocCount++;
00389             newbranch->fMemSize += branch->fLeaks[i].fSize;
00390          }
00391       free(branch->fLeaks);
00392       free(branch);
00393    }                 //loop over all old branches and rehash information
00394    free(fLeak);
00395    fLeak = newLeak;
00396    fSize = newSize;
00397 }
00398 
00399 //______________________________________________________________________________
00400 void *TMemStatManager::AddPointer(size_t  size, void *ptr)
00401 {
00402    // Add pointer to table.
00403 
00404    if (TestBit(kUserDisable) || TestBit(kStatDisable)) {
00405       return malloc(size);
00406    }
00407 
00408    Bool_t status = TestBit(kStatRoutine);
00409    SetBit(kStatRoutine, kTRUE);
00410 
00411    void *p = NULL;
00412 
00413    if (ptr == 0) {
00414       p = malloc(size);
00415       if (!p) {
00416          Error("TMemStatManager::AddPointer", "malloc failure");
00417          TMemStatManager::GetInstance()->Disable();
00418          TMemStatManager::GetInstance()->Close();
00419          _exit(1);
00420       }
00421    } else {
00422       p = realloc((char *) ptr, size);
00423       if (!p) {
00424          Error("TMemStatManager::AddPointer", "realloc failure");
00425          TMemStatManager::GetInstance()->Disable();
00426          TMemStatManager::GetInstance()->Close();
00427          _exit(1);
00428       }
00429       SetBit(kStatRoutine, status);
00430       return p;
00431    }
00432    if (status) {
00433       SetBit(kStatRoutine, status);
00434       return p;
00435    }
00436 
00437    if (!fSize)
00438       Init();
00439    ++fAllocCount;
00440    if ((fAllocCount / fSize) > 128)
00441       RehashLeak(fSize * 2);
00442    int hash = int(TString::Hash(&p, sizeof(void*)) % fSize);
00443    TMemTable_t *branch = fLeak[hash];
00444    branch->fAllocCount++;
00445    branch->fMemSize += size;
00446 
00447    fCurrentStamp.Inc(size);
00448    if ((fCurrentStamp.fTotalAllocCount - fLastStamp.fTotalAllocCount) > fAutoStampN ||
00449          (fCurrentStamp.fAllocCount - fLastStamp.fAllocCount) > Int_t(fAutoStampN) ||
00450          (fCurrentStamp.fTotalAllocSize - fLastStamp.fTotalAllocSize) > fAutoStampSize ||
00451          (fCurrentStamp.fAllocSize - fLastStamp.fAllocSize) > Int_t(fAutoStampSize)) {
00452       AddStamps();
00453       fLastStamp = fCurrentStamp;
00454       if (fAutoStampN < 0.001*fLastStamp.fTotalAllocCount) fAutoStampN = 1 + UInt_t(0.001 * fLastStamp.fTotalAllocCount);
00455       if (fAutoStampSize < 0.001*fLastStamp.fTotalAllocSize) fAutoStampSize = 1 + UInt_t(0.001 * fLastStamp.fTotalAllocSize);
00456    }
00457 
00458    for (;;) {
00459       for (int i = branch->fFirstFreeSpot; i < branch->fTableSize; ++i)
00460          if (branch->fLeaks[i].fAddress == 0) {
00461             branch->fLeaks[i].fAddress = p;
00462             branch->fLeaks[i].fSize = size;
00463             void *stptr[TMemStatStackInfo::kStackHistorySize + 1];
00464             int stackentries = TMemStatDepend::Backtrace(stptr, TMemStatStackInfo::kStackHistorySize, fUseGNUBuildinBacktrace);
00465             TMemStatStackInfo *info = STFindInfo(stackentries, stptr);
00466             info->Inc(size, this);
00467             if (info->fCurrentStamp.fStampNumber == 0) {
00468                info->MakeStamp(fStampNumber);  // add stamp after each addition
00469             }
00470             branch->fLeaks[i].fStackIndex = info->fStackID;
00471             branch->fFirstFreeSpot = i + 1;
00472             SetBit(kStatRoutine, status);
00473             return p;
00474          }
00475 
00476       int newTableSize =
00477          branch->fTableSize == 0 ? 16 : branch->fTableSize * 2;
00478       branch->fLeaks =
00479          (TMemInfo_t *) realloc(branch->fLeaks,
00480                                 sizeof(TMemInfo_t) * newTableSize);
00481       if (!branch->fLeaks) {
00482          Error("TMemStatManager::AddPointer", "realloc failure (2)");
00483          _exit(1);
00484       }
00485       memset(branch->fLeaks + branch->fTableSize, 0, sizeof(TMemInfo_t) *
00486              (newTableSize - branch->fTableSize));
00487       branch->fTableSize = newTableSize;
00488    }
00489 }
00490 
00491 //______________________________________________________________________________
00492 void TMemStatManager::FreePointer(void *p)
00493 {
00494    // Free pointer.
00495 
00496    if (p == 0)
00497       return;
00498    if (TestBit(kUserDisable) || TestBit(kStatDisable)) {
00499       free(p);
00500       return;
00501    }
00502 
00503    const Bool_t status = TestBit(kStatRoutine);
00504    SetBit(kStatRoutine, kTRUE);
00505 
00506    if (status) {
00507       SetBit(kStatRoutine, status);
00508       return;
00509    }
00510 
00511    const int hash = static_cast<int>(TString::Hash(&p, sizeof(void*)) % fSize);
00512    --fAllocCount;
00513    TMemTable_t *branch = fLeak[hash];
00514    for (int i = 0; i < branch->fTableSize; i++) {
00515       if (branch->fLeaks[i].fAddress == p) {
00516          branch->fLeaks[i].fAddress = 0;
00517          branch->fMemSize -= branch->fLeaks[i].fSize;
00518          if (i < branch->fFirstFreeSpot)
00519             branch->fFirstFreeSpot = i;
00520          free(p);
00521          TMemStatStackInfo *info =
00522             &(fStackVector[branch->fLeaks[i].fStackIndex]);
00523          info->Dec(branch->fLeaks[i].fSize, this);
00524          fCurrentStamp.Dec(branch->fLeaks[i].fSize);
00525          branch->fAllocCount--;
00526          SetBit(kStatRoutine, status);
00527          return;
00528       }
00529    }
00530    //
00531    //if try to delete non existing pointer
00532    //printf("***TMemStatManager::FreePointer: Multiple deletion %8p ** ?  \n",p);
00533    //  printf("-+-+%8p  \n",p);
00534    //free(p);
00535    if (fMultDeleteTable.fTableSize + 1 > fMultDeleteTable.fAllocCount) {
00536       int newTableSize =
00537          fMultDeleteTable.fTableSize ==
00538          0 ? 16 : fMultDeleteTable.fTableSize * 2;
00539       fMultDeleteTable.fLeaks =
00540          (TMemInfo_t *) realloc(fMultDeleteTable.fLeaks,
00541                                 sizeof(TMemInfo_t) * newTableSize);
00542       fMultDeleteTable.fAllocCount = newTableSize;
00543    }
00544 
00545    fMultDeleteTable.fLeaks[fMultDeleteTable.fTableSize].fAddress = 0;
00546    //void *sp = 0;
00547    void *stptr[TMemStatStackInfo::kStackHistorySize + 1];
00548    int stackentries = TMemStatDepend::Backtrace(stptr, TMemStatStackInfo::kStackHistorySize, fUseGNUBuildinBacktrace);
00549    TMemStatStackInfo *info = STFindInfo(stackentries/*j*/, stptr);
00550    info->Dec(0, this);
00551    fMultDeleteTable.fLeaks[fMultDeleteTable.fTableSize].fStackIndex =
00552       info->fStackID;
00553    fMultDeleteTable.fTableSize++;
00554    SetBit(kStatRoutine, status);
00555 }
00556 
00557 //______________________________________________________________________________
00558 void TMemStatManager::DumpTo(EDumpTo _DumpTo, Bool_t _clearStamps, const char *_stampName)
00559 {
00560    //write current status to file
00561    const Bool_t status = TestBit(TMemStatManager::kStatDisable);
00562    SetBit(TMemStatManager::kStatDisable, kTRUE);
00563    if (!fDumpFile.get())
00564       fDumpFile.reset( TFile::Open(g_cszFileName, "recreate") );
00565    //
00566    TTimeStamp stamp;
00567    MemInfo_t  memInfo;
00568    ProcInfo_t procInfo;
00569    gSystem->GetMemInfo(&memInfo);
00570    gSystem->GetProcInfo(&procInfo);
00571    Float_t memUsage[4] = { memInfo.fMemUsed, memInfo.fSwapUsed,
00572                            procInfo.fMemResident*0.001, procInfo.fMemVirtual*0.001};
00573    // No need to delete this pointer
00574    TTimeStamp *ptimeStamp(new TTimeStamp);
00575    // pass ownership to an auto_ptr
00576    auto_ptr<TTimeStamp> ptimeStamp_(ptimeStamp);
00577 
00578    TObjString *pnameStamp =
00579       (_stampName != 0) ? new TObjString(_stampName) : new TObjString(Form("autoStamp%d", fStampNumber));
00580    // pass ownership to an auto_ptr
00581    auto_ptr<TObjString> pnameStamp_(pnameStamp);
00582 
00583    const TMemStatManager * pmanager = this;
00584    Int_t stampNumber = fStampNumber;
00585 
00586    // pass ownership to an auto_ptr
00587    TMemStatInfoStamp *currentStamp(new TMemStatInfoStamp(fCurrentStamp));
00588    // pass ownership to an auto_ptr
00589    auto_ptr<TMemStatInfoStamp> currentStamp_(currentStamp);
00590 
00591    TTree *pDumpTo(NULL);
00592    bool bNewTree = false;
00593    switch (_DumpTo) {
00594    case kTree:
00595       if (!fDumpTree) {
00596          fDumpTree = new TTree("MemStat", "MemStat");
00597          bNewTree = true;
00598       }
00599       pDumpTo = fDumpTree;
00600       break;
00601    case kSysTree:
00602       if (!fDumpSysTree) {
00603          fDumpSysTree = new TTree("MemSys", "MemSys");
00604          bNewTree = true;
00605       }
00606       pDumpTo = fDumpSysTree;
00607       break;
00608    default: // TODO: Log me!
00609       return;
00610    }
00611 
00612    if (bNewTree) {
00613       if (kTree == _DumpTo)
00614          pDumpTo->Branch("Manager", "TMemStatManager", &pmanager);
00615       pDumpTo->Branch("StampTime.", "TTimeStamp", &ptimeStamp);
00616       pDumpTo->Branch("StampName.", "TObjString", &pnameStamp);
00617       pDumpTo->Branch("StampNumber", &stampNumber, "StampNumber/I");
00618       pDumpTo->Branch("CurrentStamp", "TMemStatInfoStamp", &currentStamp);
00619       pDumpTo->Branch("Mem0", &memUsage[0], "Mem0/F");
00620       pDumpTo->Branch("Mem1", &memUsage[1], "Mem1/F");
00621       pDumpTo->Branch("Mem2", &memUsage[2], "Mem2/F");
00622       pDumpTo->Branch("Mem3", &memUsage[3], "Mem3/F");
00623    } else {
00624       if (kTree == _DumpTo)
00625          pDumpTo->SetBranchAddress("Manager", &pmanager);
00626       pDumpTo->SetBranchAddress("StampTime.", &ptimeStamp);
00627       pDumpTo->SetBranchAddress("StampName.", &pnameStamp);
00628       pDumpTo->SetBranchAddress("StampNumber", &stampNumber);
00629       pDumpTo->SetBranchAddress("CurrentStamp", &currentStamp);
00630       pDumpTo->SetBranchAddress("Mem0", &memUsage[0]);
00631       pDumpTo->SetBranchAddress("Mem1", &memUsage[1]);
00632       pDumpTo->SetBranchAddress("Mem2", &memUsage[2]);
00633       pDumpTo->SetBranchAddress("Mem3", &memUsage[3]);
00634    }
00635 
00636    pDumpTo->Fill();
00637    pDumpTo->AutoSave("Stat");
00638    if (_clearStamps)
00639       fStampVector.clear();
00640    SetBit(TMemStatManager::kStatDisable, status);
00641 }

Generated on Tue Jul 5 14:43:52 2011 for ROOT_528-00b_version by  doxygen 1.5.1