// @(#)root/memstat:$Id$
// Author: Anar Manafov (A.Manafov@gsi.de) 2008-03-02

/*************************************************************************
* Copyright (C) 1995-2010, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/
#ifndef ROOT_TMemStatMng
#define ROOT_TMemStatMng

// STD
#include <map>
// ROOT
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TTimeStamp
#include "TTimeStamp.h"
#endif
// Memstat
#ifndef ROOT_TMemStatHook
#include "TMemStatHook.h"
#endif
#ifndef ROOT_TMemStatDef
#include "TMemStatDef.h"
#endif

class TTree;
class TFile;
class TH1I;
class TObjArray;

namespace Memstat {

   class TMemStatFAddrContainer {
      typedef std::map<ULong_t, Int_t> Container_t;
      typedef Container_t::iterator pos_type;
      typedef Container_t::value_type value_type;

   public:
      bool add(ULong_t addr, Int_t idx) {
         std::pair<pos_type, bool> ret = fContainer.insert(value_type(addr, idx));
         return (ret.second);
      }

      Int_t find(ULong_t addr) {
         pos_type iter = fContainer.find(addr);
         if(fContainer.end() == iter)
            return -1;

         return iter->second;
      }

   private:
      Container_t fContainer;
   };

   const UShort_t g_digestSize = 16;
   struct SCustomDigest {
      SCustomDigest() {
         memset(fValue, 0, g_digestSize);
      }
      SCustomDigest(UChar_t _val[g_digestSize]) {
         memcpy(fValue, _val, g_digestSize);
      }

      UChar_t fValue[g_digestSize];
   };
   inline bool operator< (const SCustomDigest &a, const SCustomDigest &b)
   {
      for(int i = 0; i < g_digestSize; ++i) {
         if(a.fValue[i] != b.fValue[i])
            return (a.fValue[i] < b.fValue[i]);
      }
      return false;
   }


   class TMemStatMng: public TObject {
      typedef std::map<SCustomDigest, Int_t> CRCSet_t;

   private:
      TMemStatMng();
      virtual ~TMemStatMng();

   public:
      void Enable();                       //enable memory statistic
      void Disable();                      //Disable memory statistic
      static TMemStatMng* GetInstance();   //get instance of class - ONLY ONE INSTANCE
      static void Close();                 //close MemStatManager
      void SetBufferSize(Int_t buffersize);
      void SetMaxCalls(Int_t maxcalls);

   public:
      //stack data members
      void SetUseGNUBuiltinBacktrace(Bool_t newVal) {
         fUseGNUBuiltinBacktrace = newVal;
      }

   protected:
#if !defined(__APPLE__)
      TMemStatHook::MallocHookFunc_t fPreviousMallocHook;    //!old malloc function
      TMemStatHook::FreeHookFunc_t fPreviousFreeHook;        //!old free function
#endif
      void Init();
      void AddPointer(void *ptr, Int_t size);    //add pointer to the table
      void FillTree();
      static void *AllocHook(size_t size, const void* /*caller*/);
      static void FreeHook(void* ptr, const void* /*caller*/);
      static void MacAllocHook(void *ptr, size_t size);
      static void MacFreeHook(void *ptr);
      Int_t generateBTID(UChar_t *CRCdigest, Int_t stackEntries,
                         void **stackPointers);


      //  memory information
      TFile* fDumpFile;               //!file to dump current information
      TTree *fDumpTree;               //!tree to dump information
      static TMemStatMng *fgInstance; // pointer to instance
      static void *fgStackTop;        // stack top pointer

      Bool_t fUseGNUBuiltinBacktrace;
      TTimeStamp fTimeStamp;
      Double_t  fBeginTime;   //time when monitoring starts
      ULong64_t fPos;         //position in memory where alloc/free happens
      Int_t     fTimems;      //10000*(current time - begin time)
      Int_t     fNBytes;      //number of bytes allocated/freed
      Int_t     fBtID;        //back trace identifier
      Int_t     fMaxCalls;    //max number of malloc/frees to register in the output Tree
      Int_t     fBufferSize;  //max number of malloc/free to keep in the buffer
      Int_t     fBufN;        //current number of alloc or free in the buffer
      ULong64_t *fBufPos;     //position in memory where alloc/free happens
      Int_t     *fBufTimems;  //10000*(current time - begin time)
      Int_t     *fBufNBytes;  //number of bytes allocated/freed
      Int_t     *fBufBtID;    //back trace identifier
      Int_t     *fIndex;      //array to sort fBufPos
      Bool_t    *fMustWrite;  //flag to write or not the entry

   private:
      TMemStatFAddrContainer fFAddrs;
      TObjArray *fFAddrsList;
      TH1I *fHbtids;
      CRCSet_t fBTChecksums;
      Int_t fBTCount;
      // for Debug. A counter of all (de)allacations.
      UInt_t  fBTIDCount;
      TNamed *fSysInfo;

      ClassDef(TMemStatMng, 0)   // a manager of memstat sessions.
   };

}

#endif
 TMemStatMng.h:1
 TMemStatMng.h:2
 TMemStatMng.h:3
 TMemStatMng.h:4
 TMemStatMng.h:5
 TMemStatMng.h:6
 TMemStatMng.h:7
 TMemStatMng.h:8
 TMemStatMng.h:9
 TMemStatMng.h:10
 TMemStatMng.h:11
 TMemStatMng.h:12
 TMemStatMng.h:13
 TMemStatMng.h:14
 TMemStatMng.h:15
 TMemStatMng.h:16
 TMemStatMng.h:17
 TMemStatMng.h:18
 TMemStatMng.h:19
 TMemStatMng.h:20
 TMemStatMng.h:21
 TMemStatMng.h:22
 TMemStatMng.h:23
 TMemStatMng.h:24
 TMemStatMng.h:25
 TMemStatMng.h:26
 TMemStatMng.h:27
 TMemStatMng.h:28
 TMemStatMng.h:29
 TMemStatMng.h:30
 TMemStatMng.h:31
 TMemStatMng.h:32
 TMemStatMng.h:33
 TMemStatMng.h:34
 TMemStatMng.h:35
 TMemStatMng.h:36
 TMemStatMng.h:37
 TMemStatMng.h:38
 TMemStatMng.h:39
 TMemStatMng.h:40
 TMemStatMng.h:41
 TMemStatMng.h:42
 TMemStatMng.h:43
 TMemStatMng.h:44
 TMemStatMng.h:45
 TMemStatMng.h:46
 TMemStatMng.h:47
 TMemStatMng.h:48
 TMemStatMng.h:49
 TMemStatMng.h:50
 TMemStatMng.h:51
 TMemStatMng.h:52
 TMemStatMng.h:53
 TMemStatMng.h:54
 TMemStatMng.h:55
 TMemStatMng.h:56
 TMemStatMng.h:57
 TMemStatMng.h:58
 TMemStatMng.h:59
 TMemStatMng.h:60
 TMemStatMng.h:61
 TMemStatMng.h:62
 TMemStatMng.h:63
 TMemStatMng.h:64
 TMemStatMng.h:65
 TMemStatMng.h:66
 TMemStatMng.h:67
 TMemStatMng.h:68
 TMemStatMng.h:69
 TMemStatMng.h:70
 TMemStatMng.h:71
 TMemStatMng.h:72
 TMemStatMng.h:73
 TMemStatMng.h:74
 TMemStatMng.h:75
 TMemStatMng.h:76
 TMemStatMng.h:77
 TMemStatMng.h:78
 TMemStatMng.h:79
 TMemStatMng.h:80
 TMemStatMng.h:81
 TMemStatMng.h:82
 TMemStatMng.h:83
 TMemStatMng.h:84
 TMemStatMng.h:85
 TMemStatMng.h:86
 TMemStatMng.h:87
 TMemStatMng.h:88
 TMemStatMng.h:89
 TMemStatMng.h:90
 TMemStatMng.h:91
 TMemStatMng.h:92
 TMemStatMng.h:93
 TMemStatMng.h:94
 TMemStatMng.h:95
 TMemStatMng.h:96
 TMemStatMng.h:97
 TMemStatMng.h:98
 TMemStatMng.h:99
 TMemStatMng.h:100
 TMemStatMng.h:101
 TMemStatMng.h:102
 TMemStatMng.h:103
 TMemStatMng.h:104
 TMemStatMng.h:105
 TMemStatMng.h:106
 TMemStatMng.h:107
 TMemStatMng.h:108
 TMemStatMng.h:109
 TMemStatMng.h:110
 TMemStatMng.h:111
 TMemStatMng.h:112
 TMemStatMng.h:113
 TMemStatMng.h:114
 TMemStatMng.h:115
 TMemStatMng.h:116
 TMemStatMng.h:117
 TMemStatMng.h:118
 TMemStatMng.h:119
 TMemStatMng.h:120
 TMemStatMng.h:121
 TMemStatMng.h:122
 TMemStatMng.h:123
 TMemStatMng.h:124
 TMemStatMng.h:125
 TMemStatMng.h:126
 TMemStatMng.h:127
 TMemStatMng.h:128
 TMemStatMng.h:129
 TMemStatMng.h:130
 TMemStatMng.h:131
 TMemStatMng.h:132
 TMemStatMng.h:133
 TMemStatMng.h:134
 TMemStatMng.h:135
 TMemStatMng.h:136
 TMemStatMng.h:137
 TMemStatMng.h:138
 TMemStatMng.h:139
 TMemStatMng.h:140
 TMemStatMng.h:141
 TMemStatMng.h:142
 TMemStatMng.h:143
 TMemStatMng.h:144
 TMemStatMng.h:145
 TMemStatMng.h:146
 TMemStatMng.h:147
 TMemStatMng.h:148
 TMemStatMng.h:149
 TMemStatMng.h:150
 TMemStatMng.h:151
 TMemStatMng.h:152
 TMemStatMng.h:153
 TMemStatMng.h:154
 TMemStatMng.h:155
 TMemStatMng.h:156
 TMemStatMng.h:157