windows-nt/Source/XPSP1/NT/base/tools/resmon/analog.h

212 lines
7.3 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*
* Title: analog.h - header file for log analyzer
*
* Description: This file provides structures and macros for log analyzer.
*
* Types:
* PoolLogRec Poolsnap structure
* MemLogRec Memsnap structure
* LogType Enumeration of known log types
*
* Macros:
*
* GET_DELTA Computes the difference between first & last entry
* GREATER_LESS_OR_EQUAL Increments trend if cur>prv, decrements if cur<prv
* PRINT_IF_TREND Prints definite or probable leaks based on trend
* MAX Returns the larger value
*
* Copyright (c) 1998 Microsoft Corporation
*
* Revision history: LarsOp (created) 12/8/98
*
*/
//
// Structure for poolsnap logs
//
typedef struct _PoolLogRec {
char Name[32];
char Type[32];
long Allocs;
long Frees;
long Diff;
long Bytes;
long PerAlloc;
} PoolLogRec;
//
// Structure for memsnap logs
//
typedef struct _MemLogRec {
DWORD Pid;
char Name[64];
long WorkingSet;
long PagedPool;
long NonPagedPool;
long PageFile;
long Commit;
long Handles;
long Threads;
} MemLogRec;
//
// Enumeration of the known log types
//
typedef enum {
MEM_LOG=0, // must be zero (see LogTypeLabels)
POOL_LOG, // must be 1 (see LogTypeLabels)
UNKNOWN_LOG_TYPE
} LogType;
//
// Array of labels to simplify printing the enumerated type
//
char *LogTypeLabels[]={"MemSnap", "PoolSnap", "Unknown"};
//
// Arbitrary buffer length
//
#define BUF_LEN 256
#define PERCENT_TO_PRINT 10
//
// GET_DELTA simply records the difference (end-begin) for specified field
//
// Args:
// delta - record to receive result values
// ptr - array of records (used to compare first and last)
// max - number of entries in the array
// field - field name to compute
//
// Returns: nothing (treat like void function)
//
#define GET_DELTA(delta, ptr, max, field) delta.field = ptr[max-1].field - ptr[0].field
//
// GREATER_LESS_OR_EQUAL calculates TrendInfo.
//
// Args:
// trend - record containing running tally
// ptr - array of records (used to compare curr and prev)
// i - index of current entry in the array
// field - field name to compare
//
// Returns: nothing (treat like void function)
//
// TrendInfo is a running tally of the periods a value went up vs.
// the periods it went down. See macro in analog.h
//
// if (curval>oldval) {
// trend++;
// } else if (curval<oldval) {
// trend--;
// } else {
// trend=trend; // stay same
// }
//
#define GREATER_LESS_OR_EQUAL(trend, ptr, i, field) \
if (ptr[i].field - ptr[i-1].field) \
trend.field += (((ptr[i].field - ptr[i-1].field) > 0) ? 1 : -1);
//
// MAX returns the larger value of the two
//
// Args: x,y: arguments of the same type where '>' is defined.
//
// Returns: the larger value
//
#define MAX(x, y) (x>y?x:y)
//
// PERCENT returns the percentage
//
// Args:
// delta - value of increase
// base - initial value
//
// Returns: the percent if base!=0, else 0
//
#define PERCENT(delta, base) (base!=0?(100*delta)/base:0)
#define VAL_AND_PERCENT(delta, ptr, field) delta.field, PERCENT(delta.field, ptr[0].field)
//
// PRINT_IF_TREND reports probable or definite leaks for any field.
//
// Args:
// ptr - array of records (used to display first and last)
// trend - record containing running tally
// delta - record containing raw differences of first and last
// max - number of entries in the array
// field - field name to compare
//
// Returns: nothing (treat like void function)
//
// Definite leak is where the value goes up every period
// Probable leak is where the value goes up most of the time
//
//
// PRINT_HEADER and PRINT_IF_TREND must agree on field widths.
//
#define PRINT_HEADER() { \
TableHeader(); \
if( bHtmlStyle ) { \
TableStart(); \
printf("<TH COLSPAN=2> %s </TH>\n",g_pszComputerName); \
printf("<TH COLSPAN=6>\n"); \
if( g_fShowExtraInfo ) { \
printf("BuildNumber=%s\n",g_pszBuildNumber); \
printf("<BR>BuildType=%s\n",g_pszBuildType); \
printf("<BR>Last SystemTime=%s\n",g_pszSystemTime); \
printf("<BR>%s\n",g_pszComments); \
} \
printf("</TH>\n"); \
TableEnd(); \
} \
TableStart(); \
TableField("%-15s", "Name" ); \
TableField("%-12s", "Probability"); \
TableField("%-12s", "Object" ); \
TableField("%10s", "Change" ); \
TableField("%10s", "Start" ); \
TableField("%10s", "End" ); \
TableField("%8s", "Percent"); \
TableField("%10s", "Rate/hour" ); \
TableEnd(); }
#define PRINT_TRAILER() { \
TableTrailer(); }
#define PRINT_IF_TREND(ptr, trend, delta, max, field) \
if (trend.field >= max/2) { \
BOOL bDefinite= (trend.field==max-1) ? 1 : 0; \
if( bDefinite || (g_ReportLevel>0) ) { \
TableStart(); \
TableField("%-15s", ptr[0].Name); \
TableField("%-12s", bDefinite ? "Definite" : "Probable"); \
TableField("%-12s", #field); \
TableNum("%10ld", delta.field); \
TableNum("%10ld", ptr[0].field); \
TableNum("%10ld", ptr[max-1].field); \
TableNum("%8ld", PERCENT(delta.field,ptr[0].field)); \
if( g_dwElapseTickCount ) { \
TableNum("%10d",Trick( delta.field ,g_dwElapseTickCount) ); \
} else { \
TableField("%-10s"," "); \
}; \
TableEnd(); \
} \
}
#define ANY_PERCENT_GREATER(delta, ptr) (\
(PERCENT(delta.WorkingSet , ptr[0].WorkingSet ) > PERCENT_TO_PRINT) || \
(PERCENT(delta.PagedPool , ptr[0].PagedPool ) > PERCENT_TO_PRINT) || \
(PERCENT(delta.NonPagedPool , ptr[0].NonPagedPool) > PERCENT_TO_PRINT) || \
(PERCENT(delta.PageFile , ptr[0].PageFile ) > PERCENT_TO_PRINT) || \
(PERCENT(delta.Commit , ptr[0].Commit ) > PERCENT_TO_PRINT) || \
(PERCENT(delta.Handles , ptr[0].Handles ) > PERCENT_TO_PRINT) || \
(PERCENT(delta.Threads , ptr[0].Threads ) > PERCENT_TO_PRINT))