175 lines
4 KiB
C
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_
|
||
|
|
||
|
|