|
|
// Copyright (c) 1999-2000 Microsoft Corporation
///======================================================================
//
// Perf.h
//
// Fill in this header file with definitions for the performance
// counters you want to use.
//
///======================================================================
#ifndef _PERF_H_
#define _PERF_H_
//**********************************************************************
//
// Modify this section for your counters
//
#define DRV_NAME "WCEUSBSH"
//
// Define PERFORMANCE to "1" turn on the cycle performance counters.
// I currently set it in the debug build (or explicitely in SOURCES for free build) since
// the free build only sees a slight gain IFF *all* debug tracing (except DBG_ERR)
// is turned off.
//
#if DBG
#if !defined(MSFT_NT_BUILD)
#define PERFORMANCE 1
#endif
#endif
//
// This is the array of counter index definitions.
// Note that when a new entry is added here that the name array
// in perf.c must be updated as well. The convention is that
// the index name should match the function name identically, with
// the PERF_ prefix.
//
enum { //
// Write path
//
PERF_Write, PERF_WriteComplete, PERF_WriteTimeout,
//
// Read path
//
PERF_StartUsbReadWorkItem, PERF_UsbRead, PERF_UsbReadCompletion, PERF_CheckForQueuedUserReads, PERF_GetUserData, PERF_PutUserData, PERF_CancelUsbReadIrp, PERF_Read, PERF_StartOrQueueIrp, PERF_StartUserRead, PERF_GetNextUserIrp, PERF_CancelCurrentRead, PERF_CancelQueuedIrp, PERF_ReadTimeout, PERF_IntervalReadTimeout, PERF_CancelUsbReadWorkItem,
//
// USB Path
//
PERF_UsbReadWritePacket,
//
// Serial path
//
PERF_ProcessSerialWaits,
//
// Utils
//
PERF_TryToCompleteCurrentIrp, PERF_RundownIrpRefs, PERF_RecycleIrp, PERF_ReuseIrp, PERF_CalculateTimeout,
//
// leave this entry alone
//
NUM_PERF_COUNTERS } PERF_INDICED;
//
// End of user-modified portion
//
//**********************************************************************
typedef struct { KSPIN_LOCK Lock; LONG Count; LARGE_INTEGER TotalCycles; } PERF_COUNTER, *PPERF_COUNTER;
#if PERFORMANCE
extern PERF_COUNTER PerfCounter[];
//
// Definition for raw bytes that generate RDTSC instruction
//
#define RDTSC(_VAR) \
_asm { \ _asm push eax \ _asm push edx \ _asm _emit 0Fh \ _asm _emit 31h \ _asm mov _VAR.LowPart, eax \ _asm mov _VAR.HighPart, edx \ _asm pop edx \ _asm pop eax \ }
//
// Definitions for performance counters that execute
// at DISPATCH_LEVEL (e.g. in DPCs) and lower IRQLs.
//
// NOTE: we read the cycle counter at the outside of the
// macros since we compensate for the overhead of the macros themselves.
//
#define PERF_ENTRY(_INDEX) \
LARGE_INTEGER _INDEX##perfStart; \ LARGE_INTEGER _INDEX##perfEnd; \ RDTSC(_INDEX##perfStart); \ InterlockedIncrement( &PerfCounter[_INDEX].Count )
#define PERF_EXIT(_INDEX) \
RDTSC(_INDEX##perfEnd); \ _INDEX##perfEnd.QuadPart -= _INDEX##perfStart.QuadPart; \ ExInterlockedAddLargeInteger( &PerfCounter[_INDEX].TotalCycles, \ _INDEX##perfEnd, \ &PerfCounter[_INDEX].Lock )
//
// Definitions for performance counters that execute
// in ISRs, and hence need no locking
//
#define PERF_ISR_ENTRY(_INDEX) PERF_ENTRY(_INDEX)
#define PERF_ISR_EXIT(_INDEX) \
_INDEX##perfEnd.QuadPart -= _INDEX##perfStart.QuadPart; \ PerfCounter[_INDEX].TotalCycles.QuadPart += _INDEX##perfEnd.QuadPart; \ RDTSC(_INDEX##perfEnd)
#else // PERFORMANCE
#define PERF_ENTRY(_INDEX)
#define PERF_EXIT(_INDEX)
#endif PERFORMANCE
//
// Externs for perf.c
//
VOID InitPerfCounters(); VOID DumpPerfCounters();
#endif _PERF_H_
|