Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
7.3 KiB

  1. /*
  2. * Title: analog.h - header file for log analyzer
  3. *
  4. * Description: This file provides structures and macros for log analyzer.
  5. *
  6. * Types:
  7. * PoolLogRec Poolsnap structure
  8. * MemLogRec Memsnap structure
  9. * LogType Enumeration of known log types
  10. *
  11. * Macros:
  12. *
  13. * GET_DELTA Computes the difference between first & last entry
  14. * GREATER_LESS_OR_EQUAL Increments trend if cur>prv, decrements if cur<prv
  15. * PRINT_IF_TREND Prints definite or probable leaks based on trend
  16. * MAX Returns the larger value
  17. *
  18. * Copyright (c) 1998 Microsoft Corporation
  19. *
  20. * Revision history: LarsOp (created) 12/8/98
  21. *
  22. */
  23. //
  24. // Structure for poolsnap logs
  25. //
  26. typedef struct _PoolLogRec {
  27. char Name[32];
  28. char Type[32];
  29. long Allocs;
  30. long Frees;
  31. long Diff;
  32. long Bytes;
  33. long PerAlloc;
  34. } PoolLogRec;
  35. //
  36. // Structure for memsnap logs
  37. //
  38. typedef struct _MemLogRec {
  39. DWORD Pid;
  40. char Name[64];
  41. long WorkingSet;
  42. long PagedPool;
  43. long NonPagedPool;
  44. long PageFile;
  45. long Commit;
  46. long Handles;
  47. long Threads;
  48. } MemLogRec;
  49. //
  50. // Enumeration of the known log types
  51. //
  52. typedef enum {
  53. MEM_LOG=0, // must be zero (see LogTypeLabels)
  54. POOL_LOG, // must be 1 (see LogTypeLabels)
  55. UNKNOWN_LOG_TYPE
  56. } LogType;
  57. //
  58. // Array of labels to simplify printing the enumerated type
  59. //
  60. char *LogTypeLabels[]={"MemSnap", "PoolSnap", "Unknown"};
  61. //
  62. // Arbitrary buffer length
  63. //
  64. #define BUF_LEN 256
  65. #define PERCENT_TO_PRINT 10
  66. //
  67. // GET_DELTA simply records the difference (end-begin) for specified field
  68. //
  69. // Args:
  70. // delta - record to receive result values
  71. // ptr - array of records (used to compare first and last)
  72. // max - number of entries in the array
  73. // field - field name to compute
  74. //
  75. // Returns: nothing (treat like void function)
  76. //
  77. #define GET_DELTA(delta, ptr, max, field) delta.field = ptr[max-1].field - ptr[0].field
  78. //
  79. // GREATER_LESS_OR_EQUAL calculates TrendInfo.
  80. //
  81. // Args:
  82. // trend - record containing running tally
  83. // ptr - array of records (used to compare curr and prev)
  84. // i - index of current entry in the array
  85. // field - field name to compare
  86. //
  87. // Returns: nothing (treat like void function)
  88. //
  89. // TrendInfo is a running tally of the periods a value went up vs.
  90. // the periods it went down. See macro in analog.h
  91. //
  92. // if (curval>oldval) {
  93. // trend++;
  94. // } else if (curval<oldval) {
  95. // trend--;
  96. // } else {
  97. // trend=trend; // stay same
  98. // }
  99. //
  100. #define GREATER_LESS_OR_EQUAL(trend, ptr, i, field) \
  101. if (ptr[i].field - ptr[i-1].field) \
  102. trend.field += (((ptr[i].field - ptr[i-1].field) > 0) ? 1 : -1);
  103. //
  104. // MAX returns the larger value of the two
  105. //
  106. // Args: x,y: arguments of the same type where '>' is defined.
  107. //
  108. // Returns: the larger value
  109. //
  110. #define MAX(x, y) (x>y?x:y)
  111. //
  112. // PERCENT returns the percentage
  113. //
  114. // Args:
  115. // delta - value of increase
  116. // base - initial value
  117. //
  118. // Returns: the percent if base!=0, else 0
  119. //
  120. #define PERCENT(delta, base) (base!=0?(100*delta)/base:0)
  121. #define VAL_AND_PERCENT(delta, ptr, field) delta.field, PERCENT(delta.field, ptr[0].field)
  122. //
  123. // PRINT_IF_TREND reports probable or definite leaks for any field.
  124. //
  125. // Args:
  126. // ptr - array of records (used to display first and last)
  127. // trend - record containing running tally
  128. // delta - record containing raw differences of first and last
  129. // max - number of entries in the array
  130. // field - field name to compare
  131. //
  132. // Returns: nothing (treat like void function)
  133. //
  134. // Definite leak is where the value goes up every period
  135. // Probable leak is where the value goes up most of the time
  136. //
  137. //
  138. // PRINT_HEADER and PRINT_IF_TREND must agree on field widths.
  139. //
  140. #define PRINT_HEADER() { \
  141. TableHeader(); \
  142. if( bHtmlStyle ) { \
  143. TableStart(); \
  144. printf("<TH COLSPAN=2> %s </TH>\n",g_pszComputerName); \
  145. printf("<TH COLSPAN=6>\n"); \
  146. if( g_fShowExtraInfo ) { \
  147. printf("BuildNumber=%s\n",g_pszBuildNumber); \
  148. printf("<BR>BuildType=%s\n",g_pszBuildType); \
  149. printf("<BR>Last SystemTime=%s\n",g_pszSystemTime); \
  150. printf("<BR>%s\n",g_pszComments); \
  151. } \
  152. printf("</TH>\n"); \
  153. TableEnd(); \
  154. } \
  155. TableStart(); \
  156. TableField("%-15s", "Name" ); \
  157. TableField("%-12s", "Probability"); \
  158. TableField("%-12s", "Object" ); \
  159. TableField("%10s", "Change" ); \
  160. TableField("%10s", "Start" ); \
  161. TableField("%10s", "End" ); \
  162. TableField("%8s", "Percent"); \
  163. TableField("%10s", "Rate/hour" ); \
  164. TableEnd(); }
  165. #define PRINT_TRAILER() { \
  166. TableTrailer(); }
  167. #define PRINT_IF_TREND(ptr, trend, delta, max, field) \
  168. if (trend.field >= max/2) { \
  169. BOOL bDefinite= (trend.field==max-1) ? 1 : 0; \
  170. if( bDefinite || (g_ReportLevel>0) ) { \
  171. TableStart(); \
  172. TableField("%-15s", ptr[0].Name); \
  173. TableField("%-12s", bDefinite ? "Definite" : "Probable"); \
  174. TableField("%-12s", #field); \
  175. TableNum("%10ld", delta.field); \
  176. TableNum("%10ld", ptr[0].field); \
  177. TableNum("%10ld", ptr[max-1].field); \
  178. TableNum("%8ld", PERCENT(delta.field,ptr[0].field)); \
  179. if( g_dwElapseTickCount ) { \
  180. TableNum("%10d",Trick( delta.field ,g_dwElapseTickCount) ); \
  181. } else { \
  182. TableField("%-10s"," "); \
  183. }; \
  184. TableEnd(); \
  185. } \
  186. }
  187. #define ANY_PERCENT_GREATER(delta, ptr) (\
  188. (PERCENT(delta.WorkingSet , ptr[0].WorkingSet ) > PERCENT_TO_PRINT) || \
  189. (PERCENT(delta.PagedPool , ptr[0].PagedPool ) > PERCENT_TO_PRINT) || \
  190. (PERCENT(delta.NonPagedPool , ptr[0].NonPagedPool) > PERCENT_TO_PRINT) || \
  191. (PERCENT(delta.PageFile , ptr[0].PageFile ) > PERCENT_TO_PRINT) || \
  192. (PERCENT(delta.Commit , ptr[0].Commit ) > PERCENT_TO_PRINT) || \
  193. (PERCENT(delta.Handles , ptr[0].Handles ) > PERCENT_TO_PRINT) || \
  194. (PERCENT(delta.Threads , ptr[0].Threads ) > PERCENT_TO_PRINT))