singrdk/base/Windows/Benchmarks/Lpc/uclient.c

286 lines
8.5 KiB
C

//++
//
//Copyright (c) Microsoft Corporation
//
//Abstract:
//
//User Mode Client Test program for the LPC subcomponent of the NTOS project
//
//--
//
// Read the processor's time stamp counter register
//
#include "ulpc.h"
_inline _declspec( naked ) UINT64 RDTSC()
{
__asm {
rdtsc;
ret;
}
}
#define GetCycleCount() RDTSC()
#define BENCH_ITERATIONS 10000
#define MAX_CLIENT_PROCESSES 9
#define MAX_CLIENT_THREADS 9
CHAR ProcessName[ 32 ];
HANDLE PortHandle = NULL;
HANDLE ClientThreadHandles[ MAX_CLIENT_THREADS ] = {NULL};
DWORD ClientThreadClientIds[ MAX_CLIENT_THREADS ];
DWORD
ClientThread(
LPVOID Context
)
{
CHAR ThreadName[ 64 ];
NTSTATUS Status = STATUS_SUCCESS;
ULONG MsgLength;
PTEB Teb = NtCurrentTeb();
ULONG64 startCount, endCount;
INT i;
Teb->ActiveRpcHandle = NULL;
strcpy( ThreadName, "Client Thread Id: " );
RtlIntegerToChar( (ULONG)Teb->ClientId.UniqueProcess, 16, 9,
ThreadName + strlen( ThreadName )
);
strcat( ThreadName, "." );
RtlIntegerToChar( (ULONG)Teb->ClientId.UniqueThread, 16, 9,
ThreadName + strlen( ThreadName )
);
EnterThread( ThreadName, (ULONG)Context );
MsgLength = 0;
while (NT_SUCCESS( Status )) {
startCount = GetCycleCount();
for (i = 0; i < BENCH_ITERATIONS; i++)
{
Status = SendRequest( 1,
ThreadName,
PortHandle,
Context,
MsgLength,
NULL,
FALSE
);
if (!NT_SUCCESS( Status ))
{
fprintf(stderr, "FAILED %d\n", i);
break;
}
}
endCount = GetCycleCount();
fprintf(stdout, "Message Bytes %d Iterations %d Cycles %I64d Cycles/Iteration %I64d\n",
MsgLength, BENCH_ITERATIONS, (endCount - startCount),
(endCount - startCount) / BENCH_ITERATIONS);
MsgLength += sizeof( ULONG );
if (MsgLength >= (TLPC_MAX_MSG_DATA_LENGTH * sizeof( ULONG ))) {
break;
}
}
if (PortHandle != NULL) {
if (!CloseHandle( PortHandle )) {
fprintf( stderr, "CloseHandle( 0x%lx ) failed - %u\n", PortHandle, GetLastError() );
}
else {
PortHandle = NULL;
}
}
fprintf( stderr, "%s %s\n",
NT_SUCCESS( Status ) ? "Exiting" : "ABORTING",
ThreadName
);
return RtlNtStatusToDosError( Status );
}
VOID
Usage( VOID )
{
fprintf( stderr, "usage: UCLIENT ClientNumber [#threads]\n" );
ExitProcess( 1 );
}
int
_cdecl
main(
int argc,
char *argv[]
)
{
NTSTATUS Status;
DWORD rc;
PORT_VIEW ClientView;
REMOTE_PORT_VIEW ServerView;
ULONG ClientNumber;
ULONG NumberOfThreads;
ULONG MaxMessageLength;
ULONG ConnectionInformationLength;
UCHAR ConnectionInformation[ 64 ];
ULONG i;
PULONG p;
PTEB Teb = NtCurrentTeb();
LARGE_INTEGER MaximumSize;
Status = STATUS_SUCCESS;
fprintf( stderr, "Entering UCLIENT User Mode LPC Test Program\n" );
if (argc < 2) {
Usage();
}
ClientNumber = xatoi( argv[ 1 ] );
if (argc < 3) {
NumberOfThreads = 1;
}
else {
NumberOfThreads = xatoi( argv[ 2 ] );
}
if (ClientNumber > MAX_CLIENT_PROCESSES ||
NumberOfThreads > MAX_CLIENT_THREADS
) {
Usage();
}
sprintf( ProcessName, "Client Process %08x", Teb->ClientId.UniqueProcess );
strcpy( ConnectionInformation, ProcessName );
ConnectionInformationLength = strlen( ProcessName ) + 1;
RtlInitUnicodeString( &PortName, PORT_NAME );
fprintf( stderr, "Creating Port Memory Section" );
MaximumSize.QuadPart = 0x4000 * NumberOfThreads;
Status = NtCreateSection( &ClientView.SectionHandle,
SECTION_MAP_READ | SECTION_MAP_WRITE,
NULL,
&MaximumSize,
PAGE_READWRITE,
SEC_COMMIT,
NULL
);
if (ShowHandleOrStatus( Status, ClientView.SectionHandle )) {
ClientView.Length = sizeof( ClientView );
ClientView.SectionOffset = 0;
ClientView.ViewSize = 0x2000;
ClientView.ViewBase = 0;
ClientView.ViewRemoteBase = 0;
ServerView.Length = sizeof( ServerView );
ServerView.ViewSize = 0;
ServerView.ViewBase = 0;
fprintf( stderr, "%s calling NtConnectPort( %wZ )\n", ProcessName, &PortName );
Status = NtConnectPort( &PortHandle,
&PortName,
&DynamicQos,
&ClientView,
&ServerView,
(PULONG)&MaxMessageLength,
(PVOID)ConnectionInformation,
(PULONG)&ConnectionInformationLength
);
if (ShowHandleOrStatus( Status, PortHandle )) {
fprintf( stderr, " MaxMessageLength: %ld\n", MaxMessageLength );
fprintf( stderr, " ConnectionInfo: (%ld) '%.*s'\n",
ConnectionInformationLength,
ConnectionInformationLength,
(PSZ)&ConnectionInformation[0]
);
fprintf( stderr, " ClientView: Base=%lx, Size=%lx, RemoteBase: %lx\n",
ClientView.ViewBase,
ClientView.ViewSize,
ClientView.ViewRemoteBase
);
fprintf( stderr, " ServerView: Base=%lx, Size=%lx\n",
ServerView.ViewBase,
ServerView.ViewSize
);
ClientMemoryBase = ClientView.ViewBase;
ClientMemorySize = ClientView.ViewSize;
ServerMemoryBase = ClientView.ViewRemoteBase;
ServerMemoryDelta = (ULONG)ServerMemoryBase -
(ULONG)ClientMemoryBase;
p = (PULONG)ClientMemoryBase;
i = ClientMemorySize;
while (i) {
fprintf( stderr, "ClientView[%lx] == %lx (%lx)\n",
p,
*p,
*p - ServerMemoryDelta
);
p += (0x1000/sizeof( ULONG ));
i -= 0x1000;
}
p = (PULONG)ServerView.ViewBase;
i = ServerView.ViewSize;
while (i) {
fprintf( stderr, "ServerView[%lx] == %lx\n", p, *p );
p += (0x1000/sizeof( ULONG ));
i -= 0x1000;
}
}
}
rc = RtlNtStatusToDosError( Status );
if (rc == NO_ERROR) {
ClientThreadHandles[ 0 ] = GetCurrentThread();
ClientThreadClientIds[ 0 ] = GetCurrentThreadId();
for (i=1; i< NumberOfThreads; i++) {
fprintf( stderr, "Creating %s, Thread %ld\n", ProcessName, i+1 );
rc = NO_ERROR;
ClientThreadHandles[ i ] = CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)ClientThread,
(LPVOID)((ClientNumber << 4) | (i+1)),
CREATE_SUSPENDED,
&ClientThreadClientIds[ i ]
);
if (ClientThreadHandles[ i ] == NULL) {
rc = GetLastError();
break;
}
}
if (rc == NO_ERROR) {
for (i=1; i<NumberOfThreads; i++) {
ResumeThread( ClientThreadHandles[ i ] );
}
ClientThread( (LPVOID)((ClientNumber << 4) | 1) );
}
}
if (rc == NO_ERROR) {
}
else {
fprintf( stderr, "UCLIENT: Initialization Failed - %u\n", rc );
ExitProcess( rc );
}
return( rc );
}