352 lines
7.2 KiB
C
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|