|
|
/*++
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; }
|