00001 #ifndef Impala_Core_Array_ArraySystem_h
00002 #define Impala_Core_Array_ArraySystem_h
00003
00004 #include <cstddef>
00005 #include <map>
00006 #include <iostream>
00007 #include "Basis/ILog.h"
00008
00009 namespace Impala
00010 {
00011 namespace Core
00012 {
00013 namespace Array
00014 {
00015
00016
00017 class ArraySystem
00018 {
00019 public:
00020
00021 ~ArraySystem()
00022 {
00023 }
00024
00025 static ArraySystem&
00026 Instance()
00027 {
00028 static ArraySystem theSystem;
00029 return theSystem;
00030 }
00031
00032 template<class StorT>
00033 StorT*
00034 Allocate(size_t n, StorT)
00035 {
00036 size_t oldMem = mMemUse;
00037 mMemUse += n * sizeof(StorT);
00038 mNrAlloc++;
00039 StorT* p = 0;
00040 try
00041 {
00042 p = (StorT*)(operator new(n * sizeof(StorT)));
00043 }
00044 catch (std::bad_alloc)
00045 {
00046 p = 0;
00047 }
00048 if (p == 0)
00049 ILOG_ERROR("Couldn't allocate " << n << " x " << sizeof(StorT));
00050 void* vp = p;
00051 ILOG_DEBUG("Alloc (0x" << vp << ") " << n << " times " << sizeof(StorT)
00052 << ", usage from " << oldMem << " to " << mMemUse);
00053 mMap[p] = SysInf(n, sizeof(StorT), mNrAlloc-1);
00054 return p;
00055 }
00056
00057 template<class StorT>
00058 void
00059 Deallocate(StorT* p, size_t n)
00060 {
00061 size_t oldMem = mMemUse;
00062 mMemUse -= n * sizeof(StorT);
00063 mNrDealloc++;
00064 void* vp = p;
00065 operator delete(vp);
00066 ILOG_DEBUG("Dealloc (0x" << vp << ") " << n << " times " << sizeof(StorT)
00067 << ", usage from " << oldMem << " to " << mMemUse);
00068 mMap.erase(p);
00069 }
00070
00071 template<class StorT>
00072 void
00073 External(size_t n, StorT* p)
00074 {
00075 size_t oldMem = mMemUse;
00076 mMemUse += n * sizeof(StorT);
00077 mNrAlloc++;
00078 ILOG_DEBUG("External (0x" << p << ") " << n << " times " << sizeof(StorT)
00079 << ", usage from " << oldMem << " to " << mMemUse);
00080 mMap[p] = SysInf(n, sizeof(StorT), mNrAlloc-1);
00081 }
00082
00083 size_t
00084 MemoryUsage() const
00085 {
00086 return mMemUse;
00087 }
00088
00089 int
00090 NrAlloc() const
00091 {
00092 return mNrAlloc;
00093 }
00094
00095 int
00096 NrDealloc() const
00097 {
00098 return mNrDealloc;
00099 }
00100
00101 void
00102 MarkMemoryUsage(bool verb = false)
00103 {
00104 mMemUseMark = mMemUse;
00105 mNrAllocMark = mNrAlloc;
00106 mNrDeallocMark = mNrDealloc;
00107 if (verb)
00108 {
00109 ILOG_INFO("marking memory usage: " << mMemUse
00110 << " nr alloc " << mNrAlloc
00111 << " nr dealloc " << mNrDealloc);
00112 DumpMap();
00113 }
00114 }
00115
00116 size_t
00117 MemoryUsageSinceMark(bool verb = false) const
00118 {
00119 if (verb)
00120 {
00121 ILOG_INFO("memory usage since mark: " << MemoryUsageSinceMark()
00122 << " nr alloc " << NrAllocMark()
00123 << " nr dealloc " << NrDeallocMark()
00124 << " alloc usage " << AllocUsageMark());
00125 ILOG_INFO(" total memory usage: " << mMemUse
00126 << " nr alloc " << mNrAlloc
00127 << " nr dealloc " << mNrDealloc
00128 << " alloc usage " << mNrAlloc - mNrDealloc);
00129 DumpMap();
00130 }
00131 return mMemUse - mMemUseMark;
00132 }
00133
00134 void
00135 CheckMemoryUsageSinceMark(bool verb = false) const
00136 {
00137 size_t memUsed = MemoryUsageSinceMark(verb);
00138 if (memUsed > 0)
00139 ILOG_INFO("Memory leak " << memUsed << ", alloc usage "
00140 << AllocUsageMark());
00141 }
00142
00143 int
00144 AllocUsageMark() const
00145 {
00146 return NrAllocMark() - NrDeallocMark();
00147 }
00148
00149 int
00150 NrAllocMark() const
00151 {
00152 return mNrAlloc - mNrAllocMark;
00153 }
00154
00155 int
00156 NrDeallocMark() const
00157 {
00158 return mNrDealloc - mNrDeallocMark;
00159 }
00160
00161 void
00162 DumpMap() const
00163 {
00164 ILOG_INFO("DumpMap start");
00165 for (SysInfMap::const_iterator i=mMap.begin() ; i!=mMap.end() ; i++)
00166 ILOG_INFO(i->second.mAllocNr << " = (0x" << i->first << ") "
00167 << i->second.mN << " elements of " << i->second.mSizeof
00168 << " bytes");
00169 ILOG_INFO("DumpMap end");
00170 }
00171
00172 private:
00173
00174 class SysInf
00175 {
00176 public:
00177 SysInf()
00178 {
00179 }
00180
00181 SysInf(size_t n, size_t siz, int al)
00182 {
00183 mN = n;
00184 mSizeof = siz;
00185 mAllocNr = al;
00186 }
00187
00188 size_t mN;
00189 size_t mSizeof;
00190 int mAllocNr;
00191 };
00192
00193 typedef std::map<void*,SysInf> SysInfMap;
00194
00195 SysInfMap mMap;
00196
00197 ArraySystem()
00198 {
00199 mMemUse = 0;
00200 mMemUseMark = 0;
00201 mNrAlloc = 0;
00202 mNrDealloc = 0;
00203 mNrAllocMark = 0;
00204 mNrDeallocMark = 0;
00205 }
00206
00207 ArraySystem(const ArraySystem&)
00208 {
00209 }
00210
00211 ArraySystem&
00212 operator=(const ArraySystem&);
00213
00214 size_t mMemUse;
00215 size_t mMemUseMark;
00216 int mNrAlloc;
00217 int mNrDealloc;
00218 int mNrAllocMark;
00219 int mNrDeallocMark;
00220
00221 ILOG_VAR_DEC;
00222
00223 };
00224
00225 ILOG_VAR_INIT(ArraySystem, Impala.Core.Array);
00226
00227 }
00228 }
00229 }
00230
00231 #endif