jdebug.hpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef JDEBUG_HPP
  14. #define JDEBUG_HPP
  15. #include "jiface.hpp"
  16. #define TIMING
  17. typedef __int64 cycle_t;
  18. __int64 jlib_decl cycle_to_nanosec(cycle_t cycles);
  19. cycle_t jlib_decl nanosec_to_cycle(__int64 cycles);
  20. cycle_t jlib_decl get_cycles_now(); // equivalent to getTSC when available
  21. double jlib_decl getCycleToNanoScale();
  22. void jlib_decl display_time(const char * title, cycle_t diff);
  23. // X86 / X86_64
  24. #if defined(_ARCH_X86_64_) || defined(_ARCH_X86_)
  25. #if defined(_WIN32) && defined (_ARCH_X86_)
  26. #pragma warning(push)
  27. #pragma warning(disable:4035)
  28. inline cycle_t getTSC() { __asm { __asm _emit 0x0f __asm _emit 0x31 } }
  29. #pragma warning(pop)
  30. #elif !defined(_WIN32)
  31. inline volatile __int64 getTSC()
  32. {
  33. cycle_t x;
  34. unsigned a, d;
  35. __asm__ volatile("rdtsc" : "=a" (a), "=d" (d));
  36. return ((cycle_t)a)|(((cycle_t)d) << 32);
  37. }
  38. #else
  39. #include <intrin.h>
  40. inline cycle_t getTSC() { return __rdtsc(); }
  41. #endif // WIN32
  42. #else
  43. // ARMFIX: cycle-count is not always available in user mode
  44. // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0338g/Bihbeabc.html
  45. // http://neocontra.blogspot.co.uk/2013/05/user-mode-performance-counters-for.html
  46. inline cycle_t getTSC() { return 0; }
  47. #endif // X86
  48. struct HardwareInfo
  49. {
  50. unsigned numCPUs;
  51. unsigned CPUSpeed; // In MHz
  52. unsigned totalMemory; // In MB
  53. unsigned primDiskSize; // In GB
  54. unsigned primFreeSize; // In GB
  55. unsigned secDiskSize; // In GB
  56. unsigned secFreeSize; // In GB
  57. unsigned NICSpeed; //
  58. };
  59. struct UserSystemTime_t
  60. {
  61. public:
  62. UserSystemTime_t() : user(0), system(0) {}
  63. unsigned user;
  64. unsigned system;
  65. };
  66. interface ITimeReportInfo
  67. {
  68. virtual void report(const char * scope, const char * description, const __int64 totaltime, const __int64 maxtime, const unsigned count) = 0;
  69. };
  70. class StringBuffer;
  71. class MemoryBuffer;
  72. struct ITimeReporter : public IInterface
  73. {
  74. virtual void addTiming(const char * scope, const char *desc, unsigned __int64 cycles) = 0;
  75. virtual void mergeTiming(const char * scope, const char *desc, const __int64 totalcycles, const __int64 maxcycles, const unsigned count) = 0;
  76. virtual unsigned numSections() = 0;
  77. virtual __int64 getTime(unsigned idx) = 0;
  78. virtual __int64 getMaxTime(unsigned idx) = 0;
  79. virtual unsigned getCount(unsigned idx) = 0;
  80. virtual StringBuffer &getScope(unsigned idx, StringBuffer &s) = 0;
  81. virtual StringBuffer &getDescription(unsigned idx, StringBuffer &s) = 0;
  82. virtual StringBuffer &getTimings(StringBuffer &s) = 0;
  83. virtual void printTimings() = 0;
  84. virtual void reset() = 0;
  85. virtual void mergeInto(ITimeReporter &other) = 0;
  86. virtual void merge(ITimeReporter &other)= 0;
  87. virtual void report(ITimeReportInfo &cb) = 0;
  88. virtual void serialize(MemoryBuffer &mb) = 0;
  89. };
  90. extern jlib_decl cycle_t oneSecInCycles;
  91. class CCycleTimer
  92. {
  93. cycle_t start_time;
  94. public:
  95. CCycleTimer()
  96. {
  97. reset();
  98. }
  99. inline void reset()
  100. {
  101. start_time = get_cycles_now();
  102. }
  103. inline cycle_t elapsedCycles()
  104. {
  105. return get_cycles_now() - start_time;
  106. }
  107. inline unsigned elapsedMs()
  108. {
  109. return static_cast<unsigned>(cycle_to_nanosec(elapsedCycles())/1000000);
  110. }
  111. };
  112. inline cycle_t queryOneSecCycles() { return oneSecInCycles; }
  113. class jlib_decl TimeSection
  114. {
  115. public:
  116. TimeSection(const char * _title);
  117. ~TimeSection();
  118. protected:
  119. const char * title;
  120. cycle_t start_time;
  121. };
  122. class jlib_decl MTimeSection
  123. {
  124. public:
  125. MTimeSection(ITimeReporter *_master, const char * scope, const char * _title);
  126. ~MTimeSection();
  127. protected:
  128. const char * scope;
  129. const char * title;
  130. cycle_t start_time;
  131. ITimeReporter *master;
  132. };
  133. #if defined(TIMING)
  134. extern jlib_decl ITimeReporter *defaultTimer; // MORE - this appears to be always exactly the same as timer. Should delete one or other of them?
  135. extern jlib_decl ITimeReporter *timer;
  136. extern jlib_decl ITimeReporter *createStdTimeReporter();
  137. extern jlib_decl ITimeReporter *createStdTimeReporter(MemoryBuffer &mb);
  138. #define TIME_SECTION(title) TimeSection glue(_timer,__LINE__)(title);
  139. #define MTIME_SECTION(master,title) MTimeSection glue(mtimer,__LINE__)(master, "workunit;" title, title);
  140. #else
  141. #define TIME_SECTION(title)
  142. #define MTIME_SECTION(master,title)
  143. #endif
  144. extern jlib_decl unsigned usTick();
  145. class jlib_decl HiresTimer
  146. {
  147. public:
  148. inline HiresTimer()
  149. {
  150. start=usTick();
  151. }
  152. inline void reset()
  153. {
  154. start=usTick();
  155. }
  156. inline double get()
  157. {
  158. return (double)(usTick()-start)/1000000;
  159. }
  160. private:
  161. unsigned start;
  162. };
  163. //===========================================================================
  164. #ifndef USING_MPATROL
  165. #ifdef _DEBUG
  166. #define LEAK_CHECK
  167. #endif
  168. #endif
  169. #ifdef LEAK_CHECK
  170. #ifdef _WIN32
  171. #include <stdio.h>
  172. #define _CRTDBG_MAP_ALLOC
  173. #include <crtdbg.h>
  174. #define CHECK_FOR_LEAKS(title) LeakChecker checker##__LINE__(title)
  175. class jlib_decl LeakChecker
  176. {
  177. public:
  178. LeakChecker(const char * _title);
  179. ~LeakChecker();
  180. protected:
  181. const char * title;
  182. _CrtMemState oldMemState;
  183. };
  184. extern jlib_decl void logLeaks (const char *logFile); // logFile may be NULL, leaks are logged to only stderr in this case
  185. extern jlib_decl void logLeaks (FILE *logHandle); // only use predefined file handles like stderr and stdout
  186. #else
  187. #define CHECK_FOR_LEAKS(title)
  188. #define logLeaks(name)
  189. #endif
  190. #else
  191. #define CHECK_FOR_LEAKS(title)
  192. #define logLeaks(name)
  193. #endif
  194. #if !defined(USING_MPATROL) && defined(_DEBUG) && (defined(_WIN32) || defined(WIN32))
  195. void jlib_decl enableMemLeakChecking(bool enable);
  196. #else
  197. #define enableMemLeakChecking(enable)
  198. #endif
  199. // Hook to be called by the performance monitor, takes stats for processor, virtual memory, disk, and thread usage
  200. interface IPerfMonHook : extends IInterface
  201. {
  202. public:
  203. virtual void processPerfStats(unsigned processorUsage, unsigned memoryUsage, unsigned memoryTotal, unsigned __int64 fistDiskUsage, unsigned __int64 firstDiskTotal, unsigned __int64 secondDiskUsage, unsigned __int64 secondDiskTotal, unsigned threadCount) = 0;
  204. virtual StringBuffer &extraLogging(StringBuffer &extra) = 0; // for extra periodic logging
  205. virtual void log(int level, const char *msg) = 0;
  206. };
  207. enum
  208. {
  209. //do nothing modes:
  210. PerfMonSilent = 0x00,
  211. //individual components:
  212. PerfMonProcMem = 0x01,
  213. PerfMonPackets = 0x02,
  214. PerfMonDiskUsage = 0x04,
  215. //default and full modes:
  216. PerfMonExtended = 0x08,
  217. #ifdef _WIN32
  218. PerfMonStandard = PerfMonProcMem
  219. #else
  220. PerfMonStandard = PerfMonProcMem|PerfMonExtended
  221. #endif
  222. };
  223. interface IUserMetric : extends IInterface
  224. {
  225. virtual unsigned __int64 queryCount() const = 0;
  226. virtual const char *queryName() const = 0;
  227. virtual const char *queryMatchString() const = 0;
  228. virtual void inc() = 0;
  229. virtual void reset() = 0;
  230. };
  231. extern jlib_decl IUserMetric * createUserMetric(const char *name, const char *matchString);
  232. typedef unsigned PerfMonMode;
  233. void jlib_decl getSystemTraceInfo(StringBuffer &str, PerfMonMode mode = PerfMonProcMem);
  234. void jlib_decl startPerformanceMonitor(unsigned interval, PerfMonMode traceMode = PerfMonStandard, IPerfMonHook * hook = NULL);
  235. void jlib_decl stopPerformanceMonitor();
  236. void jlib_decl setPerformanceMonitorPrimaryFileSystem(char const * fs); // for monitoring disk1, defaults to C: (win) or / (linux)
  237. void jlib_decl setPerformanceMonitorSecondaryFileSystem(char const * fs); // for monitoring disk2, no default
  238. unsigned jlib_decl getLatestCPUUsage();
  239. __int64 jlib_decl getTotalMem();
  240. unsigned jlib_decl setAllocHook(bool on); // bwd compat returns unsigned
  241. #if defined(__GLIBC) && !defined(_DEBUG)
  242. #if __GLIBC_PREREQ(2, 14)
  243. #define USE_JLIB_ALLOC_HOOK extern void jlib_decl jlib_init_hook(); void (* volatile __malloc_initialize_hook) (void) = jlib_init_hook;
  244. #else
  245. #define USE_JLIB_ALLOC_HOOK extern void jlib_decl jlib_init_hook(); void (* __malloc_initialize_hook) (void) = jlib_init_hook;
  246. #endif
  247. #else
  248. #define USE_JLIB_ALLOC_HOOK
  249. #endif
  250. extern jlib_decl void getHardwareInfo(HardwareInfo &hdwInfo, const char *primDiskPath = NULL, const char *secDiskPath = NULL);
  251. extern jlib_decl void getProcessTime(UserSystemTime_t & time);
  252. extern jlib_decl memsize_t getMapInfo(const char *type);
  253. extern jlib_decl void getCpuInfo(unsigned &numCPUs, unsigned &CPUSpeed);
  254. extern jlib_decl void getPeakMemUsage(memsize_t &peakVm,memsize_t &peakResident);
  255. extern jlib_decl unsigned getAffinityCpus();
  256. extern jlib_decl void printProcMap(const char *fn, bool printbody, bool printsummary, StringBuffer *lnout, MemoryBuffer *mb, bool useprintf);
  257. extern jlib_decl void PrintMemoryReport(bool full=true);
  258. extern jlib_decl void printAllocationSummary();
  259. #endif