windows-nt/Source/XPSP1/NT/base/win32/client/pperf.c
2020-09-26 16:20:57 +08:00

225 lines
5.6 KiB
C

#include "stdio.h"
#include "string.h"
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include "windows.h"
#define SPD_PROCESS_ITERATIONS 15
//
// Define local types.
//
typedef struct _PERFINFO {
LARGE_INTEGER StartTime;
LARGE_INTEGER StopTime;
ULONG ContextSwitches;
ULONG InterruptCount;
ULONG FirstLevelFills;
ULONG SecondLevelFills;
ULONG SystemCalls;
PCHAR Title;
ULONG Iterations;
} PERFINFO, *PPERFINFO;
VOID
SuspendedProcessTest(
VOID
);
VOID
FinishBenchMark (
IN PPERFINFO PerfInfo
);
VOID
StartBenchMark (
IN PCHAR Title,
IN ULONG Iterations,
IN PPERFINFO PerfInfo
);
VOID
main(
int argc,
char *argv[]
)
{
if ( !_strcmpi("just exit",GetCommandLine()) ) {
return;
}
SuspendedProcessTest();
return;
}
VOID
SuspendedProcessTest (
VOID
)
{
PERFINFO PerfInfo;
STARTUPINFO si;
PROCESS_INFORMATION pi[SPD_PROCESS_ITERATIONS];
BOOL b;
int Index;
CHAR Buffer[256];
KPRIORITY Base;
GetModuleFileName(0,Buffer,256);
RtlZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
Base = 13;
NtSetInformationProcess(
NtCurrentProcess(),
ProcessBasePriority,
(PVOID) &Base,
sizeof(Base)
);
// SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
StartBenchMark("Suspended Process Creation Benchmark)",
SPD_PROCESS_ITERATIONS,
&PerfInfo);
for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) {
b = CreateProcess(
Buffer,
"just exit",
NULL,
NULL,
TRUE,
CREATE_SUSPENDED,
NULL,
NULL,
&si,
&pi[Index]
);
if ( !b ) {
printf("failed %ld\n",Index);
}
}
//
// Print out performance statistics.
//
FinishBenchMark(&PerfInfo);
// SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
StartBenchMark("Process Startup/Exit Benchmark)",
SPD_PROCESS_ITERATIONS,
&PerfInfo);
for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) {
ResumeThread(pi[Index].hThread);
CloseHandle(pi[Index].hThread);
WaitForSingleObject(pi[Index].hProcess,-1);
CloseHandle(pi[Index].hProcess);
}
FinishBenchMark(&PerfInfo);
//
// End of event1 context switch test.
//
return;
}
VOID
FinishBenchMark (
IN PPERFINFO PerfInfo
)
{
ULONG ContextSwitches;
LARGE_INTEGER Duration;
ULONG FirstLevelFills;
ULONG InterruptCount;
ULONG Length;
ULONG Performance;
ULONG SecondLevelFills;
NTSTATUS Status;
ULONG SystemCalls;
SYSTEM_PERFORMANCE_INFORMATION SystemInfo;
//
// Print results and announce end of test.
//
NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);
Status = NtQuerySystemInformation(SystemPerformanceInformation,
(PVOID)&SystemInfo,
sizeof(SYSTEM_PERFORMANCE_INFORMATION),
NULL);
if (NT_SUCCESS(Status) == FALSE) {
printf("Failed to query performance information, status = %lx\n", Status);
return;
}
Duration = RtlLargeIntegerSubtract(PerfInfo->StopTime, PerfInfo->StartTime);
Length = Duration.LowPart / 10000;
printf(" Test time in milliseconds %d\n", Length);
printf(" Number of iterations %d\n", PerfInfo->Iterations);
Performance = PerfInfo->Iterations * 1000 / Length;
printf(" Iterations per second %d\n", Performance);
ContextSwitches = SystemInfo.ContextSwitches - PerfInfo->ContextSwitches;
FirstLevelFills = SystemInfo.FirstLevelTbFills - PerfInfo->FirstLevelFills;
InterruptCount = SystemInfo.InterruptCount - PerfInfo->InterruptCount;
SecondLevelFills = SystemInfo.SecondLevelTbFills - PerfInfo->SecondLevelFills;
SystemCalls = SystemInfo.SystemCalls - PerfInfo->SystemCalls;
printf(" First Level TB Fills %d\n", FirstLevelFills);
printf(" Second Level TB Fills %d\n", SecondLevelFills);
printf(" Number of Interrupts %d\n", InterruptCount);
printf(" Total Context Switches %d\n", ContextSwitches);
printf(" Number of System Calls %d\n", SystemCalls);
printf("*** End of Test ***\n\n");
return;
}
VOID
StartBenchMark (
IN PCHAR Title,
IN ULONG Iterations,
IN PPERFINFO PerfInfo
)
{
NTSTATUS Status;
SYSTEM_PERFORMANCE_INFORMATION SystemInfo;
//
// Announce start of test and the number of iterations.
//
printf("*** Start of test ***\n %s\n", Title);
PerfInfo->Title = Title;
PerfInfo->Iterations = Iterations;
NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
Status = NtQuerySystemInformation(SystemPerformanceInformation,
(PVOID)&SystemInfo,
sizeof(SYSTEM_PERFORMANCE_INFORMATION),
NULL);
if (NT_SUCCESS(Status) == FALSE) {
printf("Failed to query performance information, status = %lx\n", Status);
return;
}
PerfInfo->ContextSwitches = SystemInfo.ContextSwitches;
PerfInfo->FirstLevelFills = SystemInfo.FirstLevelTbFills;
PerfInfo->InterruptCount = SystemInfo.InterruptCount;
PerfInfo->SecondLevelFills = SystemInfo.SecondLevelTbFills;
PerfInfo->SystemCalls = SystemInfo.SystemCalls;
return;
}