Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

460 lines
8.7 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
winperf.c
Abstract:
Test program for checking performance of Win32 API calls
Author:
Mark Lucovsky (markl) 26-Sep-1990
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "basedll.h"
//
// Define local types.
//
#define EVENT_PAIR_ITERATIONS 20000
#define NULL_API_ITERATIONS 10000
#define DOMAIN_LOCK_ITERATIONS 40000
#define CRITICAL_SECTION_LOCK_ITERATIONS 80000
#define MUTEX_LOCK_ITERATIONS 20000
typedef struct _PERFINFO {
LARGE_INTEGER StartTime;
LARGE_INTEGER StopTime;
PCHAR Title;
ULONG Iterations;
} PERFINFO, *PPERFINFO;
VOID
StartBenchMark (
IN PCHAR Title,
IN ULONG Iterations,
IN PPERFINFO PerfInfo
);
VOID
FinishBenchMark (
IN PPERFINFO PerfInfo
);
VOID
GetTickCountTest(
VOID
);
VOID
EventPairTest (
VOID
);
VOID
QuickLpcTest (
VOID
);
VOID
SlowLpcTest (
VOID
);
VOID
DomainLockTest (
VOID
);
VOID
CriticalSectionLockTest (
VOID
);
VOID
MutexLockTest (
VOID
);
DWORD
main(
int argc,
char *argv[],
char *envp[]
)
{
(VOID)argc;
(VOID)argv;
(VOID)envp;
GetTickCountTest();
EventPairTest();
QuickLpcTest();
SlowLpcTest();
DomainLockTest();
CriticalSectionLockTest();
MutexLockTest();
ExitProcess(0);
}
HANDLE EventPair;
VOID
EventPairClient(
LPVOID ThreadParameter
)
{
NTSTATUS Status;
//
// Client does a NtSetLowWaitHighEventPair
//
do {
Status = NtSetLowWaitHighEventPair(EventPair);
}
while (NT_SUCCESS(Status));
ExitThread((DWORD)Status);
}
VOID
EventPairTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
HANDLE Thread;
DWORD tid;
ASSERT(NT_SUCCESS(NtCreateEventPair(&EventPair,EVENT_PAIR_ALL_ACCESS,NULL)));
Thread = CreateThread(NULL,0L,EventPairClient,(LPVOID)99,0,&tid);
Index = EVENT_PAIR_ITERATIONS;
StartBenchMark("Event Pair Benchmark",
EVENT_PAIR_ITERATIONS, &PerfInfo);
NtWaitLowEventPair(EventPair);
while (Index--) {
NtSetHighWaitLowEventPair(EventPair);
}
FinishBenchMark(&PerfInfo);
NtAlertThread(Thread);
CloseHandle(Thread);
CloseHandle(EventPair);
return;
}
VOID
GetTickCountTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
HANDLE Thread;
Index = EVENT_PAIR_ITERATIONS;
StartBenchMark("Get Tick Count Benchmark",
EVENT_PAIR_ITERATIONS, &PerfInfo);
while (Index--) {
GetTickCount();
}
FinishBenchMark(&PerfInfo);
return;
}
VOID
QuickLpcTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
PCSR_NULLAPICALL_MSG Msg;
QLPC_ACTION Action;
CsrClientThreadConnect();
Index = NULL_API_ITERATIONS;
StartBenchMark("Quick Lpc Benchmark (no data)",
NULL_API_ITERATIONS, &PerfInfo);
while (Index--) {
Msg = (PCSR_NULLAPICALL_MSG)
CsrClientPushMessage( CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
BasepNullApiCall
),
sizeof( CSR_NULLAPICALL_MSG )
);
Msg->CountArguments = 0;
ASSERT( CsrClientSendMessage( (PVOID) Msg, &Action ) == 0 );
CsrClientPopMessage( (PVOID) Msg );
}
FinishBenchMark(&PerfInfo);
Index = NULL_API_ITERATIONS;
StartBenchMark("Quick Lpc Benchmark (40 bytes of data)",
NULL_API_ITERATIONS, &PerfInfo);
while (Index--) {
Msg = (PCSR_NULLAPICALL_MSG)
CsrClientPushMessage( CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
BasepNullApiCall
),
sizeof( CSR_NULLAPICALL_MSG )
);
Msg->CountArguments = -10;
Msg->FastArguments[ 0 ] = 0;
Msg->FastArguments[ 1 ] = 1;
Msg->FastArguments[ 2 ] = 2;
Msg->FastArguments[ 3 ] = 3;
Msg->FastArguments[ 4 ] = 4;
Msg->FastArguments[ 5 ] = 5;
Msg->FastArguments[ 6 ] = 6;
Msg->FastArguments[ 7 ] = 7;
Msg->FastArguments[ 8 ] = 8;
Msg->FastArguments[ 9 ] = 9;
ASSERT( CsrClientSendMessage( (PVOID) Msg, &Action ) == 10 );
CsrClientPopMessage( (PVOID) Msg );
}
FinishBenchMark(&PerfInfo);
return;
}
ULONG
BaseNullApiCall(
IN LONG CountArguments,
IN PCHAR *Arguments OPTIONAL
);
ULONG NullApiImmediateArguments[] = {
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
};
PCHAR NullApiTextArguments[] = {
"123456789012345678901234567890",
"123456789012345678901234567890",
"123456789012345678901234567890123456789012345678901234567890",
NULL
};
VOID
SlowLpcTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
Index = NULL_API_ITERATIONS;
StartBenchMark("Normal Lpc Benchmark (no data)",
NULL_API_ITERATIONS, &PerfInfo);
while (Index--) {
BaseNullApiCall( 0, (PCHAR *)NULL );
}
FinishBenchMark(&PerfInfo);
Index = NULL_API_ITERATIONS;
StartBenchMark("Normal Lpc Benchmark (64 bytes of immediate data)",
NULL_API_ITERATIONS, &PerfInfo);
while (Index--) {
BaseNullApiCall( -10, (PCHAR *)NullApiImmediateArguments );
}
FinishBenchMark(&PerfInfo);
Index = NULL_API_ITERATIONS;
StartBenchMark("Normal Lpc Benchmark (124 bytes of data)",
NULL_API_ITERATIONS, &PerfInfo);
while (Index--) {
BaseNullApiCall( 3, NullApiTextArguments );
}
FinishBenchMark(&PerfInfo);
return;
}
VOID
DomainLockTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
//
// Announce start of benchmark and capture performance parmeters.
//
StartBenchMark("Domain Lock Benchmark",
DOMAIN_LOCK_ITERATIONS, &PerfInfo);
for (Index = 0; Index < DOMAIN_LOCK_ITERATIONS; Index += 1) {
NtLockDisplayGroup(0);
NtUnlockDisplayGroup(0);
}
//
// Print out performance statistics.
//
FinishBenchMark(&PerfInfo);
return;
}
VOID
CriticalSectionLockTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
CRITICAL_SECTION Crit;
InitializeCriticalSection(&Crit);
//
// Announce start of benchmark and capture performance parmeters.
//
StartBenchMark("Critical Section Benchmark",
CRITICAL_SECTION_LOCK_ITERATIONS, &PerfInfo);
//
// Repeatedly call a short system service.
//
for (Index = 0; Index < CRITICAL_SECTION_LOCK_ITERATIONS; Index += 1) {
EnterCriticalSection(&Crit);
LeaveCriticalSection(&Crit);
}
//
// Print out performance statistics.
//
FinishBenchMark(&PerfInfo);
return;
}
VOID
MutexLockTest (
VOID
)
{
ULONG Index;
PERFINFO PerfInfo;
HANDLE Mutex;
Mutex = CreateMutex(NULL,FALSE,NULL);
//
// Announce start of benchmark and capture performance parmeters.
//
StartBenchMark("Mutex Benchmark",
MUTEX_LOCK_ITERATIONS, &PerfInfo);
//
// Repeatedly call a short system service.
//
for (Index = 0; Index < MUTEX_LOCK_ITERATIONS; Index += 1) {
WaitForSingleObject(Mutex,-1);
ReleaseMutex(Mutex);
}
//
// Print out performance statistics.
//
FinishBenchMark(&PerfInfo);
return;
}
VOID
FinishBenchMark (
IN PPERFINFO PerfInfo
)
{
LARGE_INTEGER Duration;
ULONG Length;
ULONG Performance;
//
// Print results and announce end of test.
//
NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);
Duration = RtlLargeIntegerSubtract(PerfInfo->StopTime, PerfInfo->StartTime);
Length = Duration.LowPart / 10000;
DbgPrint(" Test time in milliseconds %d\n", Length);
DbgPrint(" Number of iterations %d\n", PerfInfo->Iterations);
Performance = PerfInfo->Iterations * 1000 / Length;
DbgPrint(" Iterations per second %d\n", Performance);
DbgPrint("*** End of Test ***\n\n");
return;
}
VOID
StartBenchMark (
IN PCHAR Title,
IN ULONG Iterations,
IN PPERFINFO PerfInfo
)
{
//
// Announce start of test and the number of iterations.
//
DbgPrint("*** Start of test ***\n %s\n", Title);
PerfInfo->Title = Title;
PerfInfo->Iterations = Iterations;
NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
return;
}