00001 #ifndef Impala_Process_ProcessInfo_h 00002 #define Impala_Process_ProcessInfo_h 00003 00004 #ifdef PSAPI_USED 00005 #include <psapi.h> 00006 #endif 00007 00008 inline bool 00009 PsApiUsed() 00010 { 00011 #ifdef PSAPI_USED 00012 return true; 00013 #else 00014 return false; 00015 #endif 00016 } 00017 00018 #include "Basis/ILog.h" 00019 00020 namespace Impala 00021 { 00022 namespace Process 00023 { 00024 00025 //* returns -1 if not supported; -2 if retrieval failed 00026 inline const Int64 00027 GetMemUsage() 00028 { 00029 Int64 usage = -1; 00030 #ifdef PSAPI_USED 00031 PROCESS_MEMORY_COUNTERS info; 00032 bool result = GetProcessMemoryInfo( 00033 GetCurrentProcess(), &info, sizeof(info)); 00034 usage = result ? info.WorkingSetSize : -2; 00035 #endif 00036 return usage; 00037 } 00038 00039 00040 /**************************************************************************** 00041 * This class provides support for memory usage tracing; 00042 * currently for Windows only; 00043 * 00044 * possible extensions yet to implement: 00045 * - option to store state between calls for e.g. table/graph presentation 00046 * this would however aggravate the side effect that memory tracing 00047 * itself consumes memory 00048 * - have instances support "nested" calls of MarkFrom/To 00049 * - add timing info 00050 * - add linking of (info contained in) different instances for a more 00051 * complete overview 00052 ****************************************************************************/ 00053 00054 class ProcessInfo 00055 { 00056 00057 public: 00058 00059 ProcessInfo(CString tag, int dumpFreq = 0) : mTag(tag), mDumpFreq(dumpFreq) 00060 { 00061 mIsActive = false; 00062 mNetMemIncr = 0; 00063 mMemFrom = 0; 00064 mNrCalls = 0; 00065 mNrCallsIncr = 0; 00066 mNrCallsDecr = 0; 00067 } 00068 00069 virtual 00070 ~ProcessInfo() 00071 { 00072 } 00073 00074 void 00075 MarkFrom() 00076 { 00077 if (mIsActive) 00078 { 00079 ILOG_WARN("Already active (" << mTag << ")"); 00080 return; 00081 } 00082 00083 mMemFrom = GetMemUsage(); 00084 mIsActive = true; 00085 } 00086 00087 void 00088 MarkTo() 00089 { 00090 if (!mIsActive) 00091 { 00092 ILOG_WARN("Not active (" << mTag << ")"); 00093 return; 00094 } 00095 00096 mNrCalls++; 00097 Int64 memTo = GetMemUsage(); 00098 Int64 memIncr = memTo - mMemFrom; 00099 if (memIncr != 0) 00100 { 00101 if (mMemFrom < memTo) 00102 mNrCallsIncr++; 00103 else 00104 mNrCallsDecr++; 00105 mNetMemIncr += memIncr; 00106 } 00107 mIsActive = false; 00108 00109 if (mDumpFreq > 0) 00110 if (mNrCalls % mDumpFreq == 0) 00111 Dump(); 00112 } 00113 00114 void 00115 Dump() 00116 { 00117 if (mIsActive) 00118 ILOG_WARN("Still active (" << mTag << ")"); 00119 00120 ILOG_INFO("Memory info (" << mTag << ") : " << 00121 "total_calls=" << mNrCalls << 00122 ", total_mem_incr=" << mNetMemIncr << 00123 ", avg_mem_incr=" << (mNetMemIncr / Int64(mNrCalls)) << 00124 ", calls_incr=" << mNrCallsIncr << 00125 ", calls_decr=" << mNrCallsDecr); 00126 } 00127 00128 private: 00129 00130 String mTag; 00131 int mDumpFreq; 00132 Int64 mNetMemIncr; 00133 Int64 mMemFrom; 00134 int mNrCalls; 00135 int mNrCallsIncr; 00136 int mNrCallsDecr; 00137 bool mIsActive; 00138 00139 ILOG_VAR_DECL; 00140 00141 }; //class 00142 00143 ILOG_VAR_INIT(ProcessInfo, Impala.Process); 00144 00145 } // namespace 00146 } // namespace 00147 00148 #endif