?? testpdma.c
字號:
#include <windows.h>
#include <stdio.h>
#define MAX_ERROR_BUFFER 256
#define MAX_DATA_BUFFER 128*1024
#define VALID_READ_SIZE 60*1024
#define FILL_MEMORY_BYTE 0x42
#define LARGE_BUFFER_SIZE 60*1024
#define MEDIUM_BUFFER_SIZE 30*1024
#define SMALL_BUFFER_SIZE 8*1024
#define MAX_CONCURRENT_IO 20
#define DEFAULT_IO_COUNT 10000
typedef struct _BUFFER_INFO {
OVERLAPPED Overlapped; // The OVERLAPPED structure MUST be first in this
// structure or the completion port I/O will fail.
LPVOID DataBuffer;
DWORD Length;
} BUFFER_INFO, *PBUFFER_INFO;
#define FLAG_VERBOSE_MODE 0x0001
#define FLAG_TEST_SYNC 0x0010
#define FLAG_TEST_ASYNC 0x0020
#define FLAG_TESTS_ENABLED 0x00F0
#define PCI_DEVICE_NAME "pcidma"
#define NOTHING
typedef struct _USER_PARMS {
LONG LoopCount;
USHORT Flags;
UCHAR DeviceNumber[MAX_PATH];
} USER_PARMS, *PUSER_PARMS;
DWORD
AsyncTests(
IN LPCTSTR DeviceName,
IN PUSER_PARMS UserParms
);
VOID
DisplayUsage(
IN PUCHAR ProgramName
);
DWORD
DoAsyncIo(
IN HANDLE FileHandle,
IN PBUFFER_INFO BufferInfo,
IN USHORT NumberOfBuffers,
IN PUSER_PARMS UserParms
);
DWORD
FillInDataStructures(
IN PBUFFER_INFO BufferInfo,
IN USHORT NumberOfBuffers,
IN PUSER_PARMS UserParms
);
DWORD
NonOverlappedTests(
IN LPCTSTR DeviceName
);
VOID
PrintError(
IN DWORD ErrorCode
);
DWORD
ReadTest(
IN HANDLE FileHandle,
IN LPVOID DataBuffer,
IN DWORD BufferSize
);
VOID
ReleaseBuffers(
IN PBUFFER_INFO BufferInfo,
IN USHORT NumberOfBuffers
);
BOOLEAN
VerifyInputParameters(
IN SHORT ArgC,
IN PCHAR ArgV[],
IN PUSER_PARMS UserParms
);
DWORD
__cdecl
main(
int argc,
char *argv[]
)
{
DWORD errorCode;
UCHAR deviceName[MAX_PATH];
USER_PARMS userParms;
ZeroMemory(&userParms, sizeof(USER_PARMS));
//
// Verify user input parameters.
//
if (!VerifyInputParameters((SHORT)argc,
argv,
&userParms
)) {
return ERROR_INVALID_PARAMETER;
}
//
// Copy the device name into the name buffer.
//
strcpy(deviceName, "\\\\.\\");
strcat(deviceName, PCI_DEVICE_NAME);
strcat(deviceName, userParms.DeviceNumber);
printf("Testing device: %s \n", deviceName);
//
// Process non-overlapped tests.
//
if (userParms.Flags & FLAG_TEST_SYNC) {
printf("\n");
printf("*********************\n");
printf("* Synchronous tests *\n");
printf("*********************\n");
printf("\n");
errorCode = NonOverlappedTests(deviceName);
if (errorCode != NO_ERROR) {
return errorCode;
}
}
//
// Process overlapped tests.
//
if (userParms.Flags & FLAG_TEST_ASYNC) {
printf("\n");
printf("**********************\n");
printf("* Asynchronous tests *\n");
printf("**********************\n");
printf("\n");
errorCode = AsyncTests(deviceName,
&userParms
);
//
// Fall through...
//
}
return errorCode;
} // main
DWORD
AsyncTests(
IN LPCTSTR DeviceName,
PUSER_PARMS UserParms
)
{
DWORD errorCode;
HANDLE fileHandle;
BUFFER_INFO bufferInfo[MAX_CONCURRENT_IO];
//
// Open the device.
//
fileHandle = CreateFile(DeviceName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (fileHandle == INVALID_HANDLE_VALUE) {
errorCode = GetLastError();
printf("Unable to open device. Error: %d \n", errorCode);
PrintError(errorCode);
return errorCode;
}
//
// Fill in data structures.
//
errorCode = FillInDataStructures(bufferInfo,
MAX_CONCURRENT_IO,
UserParms
);
if (errorCode != NO_ERROR) {
return errorCode;
}
//
// Try some I/O.
//
DoAsyncIo(fileHandle,
bufferInfo,
MAX_CONCURRENT_IO,
UserParms
);
//
// Close device handle.
//
CloseHandle(fileHandle);
//
// Release memory.
//
ReleaseBuffers(bufferInfo,
MAX_CONCURRENT_IO
);
return NO_ERROR;
} // AsyncTests
VOID
DisplayUsage(
IN PUCHAR ProgramName
)
{
printf("\n");
printf("Usage: %s [-?] [[-a | -s] [-d##] [-t##] [-v]] \n", ProgramName);
printf("\n");
printf(" Options: \n");
printf("\n");
printf(" -? Displays this help screen \n");
printf(" -a Enable asynchronous tests \n");
printf(" -d## Device number, zero-based. Zero is the default. \n");
printf(" -s Enable synchronous tests \n");
printf(" -t## Total number of Asynchronous I/Os to test (default = %d) \n",
DEFAULT_IO_COUNT);
printf(" -v Verbose mode \n");
printf("\n");
printf("\n");
printf(" All numbers are assumed decimal. \n");
printf("\n");
} // DisplayUsage
DWORD
DoAsyncIo(
IN HANDLE FileHandle,
IN PBUFFER_INFO BufferInfo,
IN USHORT NumberOfBuffers,
IN PUSER_PARMS UserParms
)
{
PBUFFER_INFO tempBufferInfo;
HANDLE completionPort;
LONG pendingCount = 0;
LONG totalCount = 0;
DWORD errorCode;
DWORD bytesReturned;
DWORD keyCompletion;
LPOVERLAPPED ovCompletion;
USHORT i;
BOOLEAN verboseMode;
verboseMode = UserParms->Flags & FLAG_VERBOSE_MODE;
//
// Create the completion port.
//
completionPort = CreateIoCompletionPort(FileHandle,
NULL,
0,
1
);
if (INVALID_HANDLE_VALUE == completionPort) {
errorCode = GetLastError();
printf("CreateIoCompletionPort failed %d \n", errorCode);
PrintError(errorCode);
return errorCode;
}
//
// Fire off the first set of reads.
//
tempBufferInfo = BufferInfo;
for (i = 0; i < NumberOfBuffers; i++) {
if (!ReadFile(FileHandle,
tempBufferInfo->DataBuffer,
tempBufferInfo->Length,
&bytesReturned,
&tempBufferInfo->Overlapped
)) {
errorCode = GetLastError();
if (errorCode == ERROR_IO_PENDING) {
if (verboseMode) {
printf("Pending I/O # %d \n", tempBufferInfo->Overlapped.Offset);
}
pendingCount++;
} else {
printf("ReadFile for buffer %d failed \n", i);
}
} else {
printf("ReadFile completed for buffer %d \n", i);
}
//
// Point to next buffer.
//
tempBufferInfo++;
}
printf("Start: %d reads pending \n", pendingCount);
//
// Add the pending count to the total count.
//
totalCount = pendingCount;
printf("Entering main pending loop... \n");
if (UserParms->LoopCount < MAX_CONCURRENT_IO) {
UserParms->LoopCount = DEFAULT_IO_COUNT;
}
while (totalCount < UserParms->LoopCount) {
//
// Wait for an I/O to complete.
//
if (!GetQueuedCompletionStatus(completionPort,
&bytesReturned,
&keyCompletion,
&ovCompletion,
INFINITE
)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -