windows-nt/Source/XPSP1/NT/sdktools/vdmperf/calcperf.c
2020-09-26 16:20:57 +08:00

352 lines
7.2 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
CalcPerf.c
Abstract:
calculate perfoemance statistics
Author:
Environment:
Win32
Revision History:
10-20-91 Initial version
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <assert.h>
#include "calcperf.h"
SYSTEM_VDM_INSTEMUL_INFO PerfInfo;
SYSTEM_VDM_INSTEMUL_INFO PreviousPerfInfo;
//
// make the maximum for pages available a "grow only" max. (since the
// amount of memory in a machine is limited. Set to 1 Mbytes here.
//
ULONG PgAvailMax = 16384;
ULONG PreviousInterruptCount;
ULONG InterruptCount;
ULONG
InitPerfInfo()
/*++
Routine Description:
Initialize data for perf measurements
Arguments:
None
Return Value:
Number of system processors (0 if error)
Revision History:
10-21-91 Initial code
--*/
{
NTSTATUS Status;
Status = NtQuerySystemInformation(
SystemVdmInstemulInformation,
&PerfInfo,
sizeof(PerfInfo),
NULL
);
if ( !NT_SUCCESS(Status) ) {
ExitProcess(1);
}
PreviousPerfInfo = PerfInfo;
return(0);
}
BOOL
CalcCpuTime(
PDISPLAY_ITEM PerfListItem
)
/*++
Routine Description:
calculate and return %cpu time and time periods
Arguments:
None
Return Value:
Revision History:
10-21-91 Initial code
--*/
{
NTSTATUS Status;
Status = NtQuerySystemInformation(
SystemVdmInstemulInformation,
&PerfInfo,
sizeof(PerfInfo),
NULL
);
if ( !NT_SUCCESS(Status) ) {
ExitProcess(1);
}
PerfListItem[IX_PUSHF].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_PUSHF].TotalTime[0],
delta(OpcodePUSHF),
&PerfListItem[IX_PUSHF].Max);
PerfListItem[IX_POPF].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_POPF].TotalTime[0],
delta(OpcodePOPF),
&PerfListItem[IX_POPF].Max);
PerfListItem[IX_IRET].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_IRET].TotalTime[0],
delta(OpcodeIRET),
&PerfListItem[IX_IRET].Max);
PerfListItem[IX_HLT].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_HLT].TotalTime[0],
delta(OpcodeHLT),
&PerfListItem[IX_HLT].Max);
PerfListItem[IX_CLI].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_CLI].TotalTime[0],
delta(OpcodeCLI),
&PerfListItem[IX_CLI].Max);
PerfListItem[IX_STI].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_STI].TotalTime[0],
delta(OpcodeSTI),
&PerfListItem[IX_STI].Max);
PerfListItem[IX_BOP].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_BOP].TotalTime[0],
delta(BopCount),
&PerfListItem[IX_BOP].Max);
PerfListItem[IX_SEGNOTP].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_SEGNOTP].TotalTime[0],
delta(SegmentNotPresent),
&PerfListItem[IX_SEGNOTP].Max);
PerfListItem[IX_VDMOPCODEF].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_VDMOPCODEF].TotalTime[0],
delta(VdmOpcode0F),
&PerfListItem[IX_VDMOPCODEF].Max);
PerfListItem[IX_INB].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_INB].TotalTime[0],
delta(OpcodeINB),
&PerfListItem[IX_INB].Max);
PerfListItem[IX_INW].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_INW].TotalTime[0],
delta(OpcodeINW),
&PerfListItem[IX_INW].Max);
PerfListItem[IX_OUTB].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_OUTB].TotalTime[0],
delta(OpcodeOUTB),
&PerfListItem[IX_OUTB].Max);
PerfListItem[IX_OUTW].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_OUTW].TotalTime[0],
delta(OpcodeOUTW),
&PerfListItem[IX_OUTW].Max);
PerfListItem[IX_INSW].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_INSW].TotalTime[0],
delta(OpcodeINSW),
&PerfListItem[IX_INSW].Max);
PerfListItem[IX_OUTSB].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_OUTSB].TotalTime[0],
delta(OpcodeOUTSB),
&PerfListItem[IX_OUTSB].Max);
PerfListItem[IX_OUTSW].ChangeScale = UpdatePerfInfo(
&PerfListItem[IX_OUTSW].TotalTime[0],
delta(OpcodeOUTSW),
&PerfListItem[IX_OUTSW].Max);
PreviousPerfInfo = PerfInfo;
return(TRUE);
}
BOOL
UpdatePerfInfo(
PULONG DataPointer,
ULONG NewDataValue,
PULONG OldMaxValue
)
/*++
Routine Description:
Shift array of DATA_LIST_LENGTH USORTS and add the new value to the
start of list
Arguments:
DataPointer - Pointer to the start of a DATA_LIST_LENGTH array
NewDataValue - Data element to be added
OldMaxValue - Scale value
Return Value:
TRUE is MaxValue must be increased or decreased
Revision History:
10-21-91 Initial code
--*/
{
ULONG Index;
ULONG ScanMax;
//
// Shift DataArray while keeping track of the max value
//
//
// Set temp max to 100 to init a minimum maximum
//
ScanMax = 100;
for (Index=DATA_LIST_LENGTH-1;Index>=1;Index--) {
DataPointer[Index] = DataPointer[Index-1];
if (DataPointer[Index] > ScanMax) {
ScanMax = DataPointer[Index];
}
}
//
// add and check first value
//
DataPointer[0] = NewDataValue;
if (NewDataValue > ScanMax) {
ScanMax = NewDataValue;
}
//
// If OldMaxValue = NULL then do not do a max limit check
//
if (OldMaxValue == NULL) {
return(FALSE);
}
//
// If Max values changed then undate the new max
// value and return TRUE.
//
if (ScanMax != *OldMaxValue) {
*OldMaxValue = ScanMax;
return(TRUE);
}
return(FALSE);
}
VOID
InitListData(
PDISPLAY_ITEM PerfListItem,
ULONG NumberOfItems
)
/*++
Routine Description:
Init all perf data structures
Arguments:
PerfListItem - array of all perf categories
NumberOfItems - Number of items to init
Return Value:
Revision History:
10-21-91 Initial code
--*/
{
ULONG ListIndex,DataIndex;
for (ListIndex=0;ListIndex<NumberOfItems;ListIndex++) {
PerfListItem[ListIndex].Max = 100;
PerfListItem[ListIndex].ChangeScale = FALSE;
for (DataIndex=0;DataIndex<DATA_LIST_LENGTH;DataIndex++) {
PerfListItem[ListIndex].TotalTime[DataIndex] = 0;
PerfListItem[ListIndex].KernelTime[DataIndex] = 0;
PerfListItem[ListIndex].UserTime[DataIndex] = 0;
}
}
}