windows-nt/Source/XPSP1/NT/drivers/wdm/usb/driver/wceusbsh/perf.h
2020-09-26 16:20:57 +08:00

175 lines
4 KiB
C

// 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_