|
|
#include "windows.h"
#include "stdio.h"
//
// Set by the master when it isn't going to do the tests anymore.
// Manual Reset
//
HANDLE AllDoneEvent;
//
// Set by the thread to tell the master to go ahead and write.
// Auto reset.
//
HANDLE WriteWaitEvent;
//
// Set by the master to indicate that the timeouts have been
// set to the proper value and it's ok to proceed with the reads.
// Auto reset.
//
HANDLE ProceedWithReads;
//
// Set by the thread to indicate that it is ok for the master
// to proceed with the next write loop.
// Auto reset.
//
HANDLE ProceedWithNextWriteLoop;
//
// Handle to the comm port.
//
HANDLE ComHandle; OVERLAPPED ReadOverLap = {0}; OVERLAPPED WriteOverLap = {0};
DWORD ReadThread( LPVOID ThreadCount ) {
UCHAR buff[10]; DWORD i; DWORD startOfWait; float waitTimeSoFar; DWORD numberActuallyRead;
//
// Keep doing these tests until the master sets the all done signal.
//
while (WaitForSingleObject( AllDoneEvent, 0 ) == WAIT_TIMEOUT) {
WaitForSingleObject( ProceedWithReads, INFINITE );
waitTimeSoFar = 0.0;
//
// Execute the read 10 times. Do the wait for
// overlapped. We only go into the GetOverlapped code
// when the overlapped write code completes
// we capture the time just before the overlapped and
// just after the overlapped. We add up all the
// milliseconds it took for the getoverlapped to complete
// and we average them and print out the result.
//
for ( i = 0; i <= 9; i++ ) {
if (ReadFile( ComHandle, &buff[0], 10, &numberActuallyRead, &ReadOverLap )) {
printf("Didn't get the read error\n"); exit(1);
}
if (GetLastError() != ERROR_IO_PENDING) {
printf("Didn't get pending\n"); exit(1);
}
//
// Tell the write to go ahead.
//
SetEvent(WriteWaitEvent);
//
// Wait for the event that is set by the write.
//
WaitForSingleObject( WriteOverLap.hEvent, INFINITE );
startOfWait = GetTickCount();
if (!GetOverlappedResult( ComHandle, &ReadOverLap, &numberActuallyRead, TRUE )) {
printf("getover returned false\n"); exit(1);
} waitTimeSoFar += GetTickCount() - startOfWait; if (numberActuallyRead != 5) {
printf("Wrong amount in IO\n"); exit(1);
}
} printf("Total Time: %f - average time: %f\n", waitTimeSoFar,waitTimeSoFar/10.0);
SetEvent(ProceedWithNextWriteLoop);
}
return 1;
}
int __cdecl main(int argc, char *argv[]) {
DWORD startingMilli = 100; DWORD endingMilli = 20000; DWORD currentMilli; HANDLE threadHandle; CHAR *myPort = "COM1"; DCB myDcb; DWORD junk; COMMTIMEOUTS myTimeOuts; DWORD numberActuallyWritten; UCHAR buff[5] = {0,1,2,3,4};
if (argc > 1) {
sscanf(argv[1],"%d",&startingMilli);
if (argc > 2) {
sscanf(argv[2],"%d",&endingMilli);
if (argc > 3) {
myPort = argv[3];
}
}
}
if ((ComHandle = CreateFile( myPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL )) == ((HANDLE)-1)) {
printf("Couldn't open the port\n"); exit(1);
}
if (!GetCommState( ComHandle, &myDcb )) {
printf("Cound't get the comm state\n"); exit(1);
}
myDcb.BaudRate = 19200; myDcb.ByteSize = 8; myDcb.StopBits = ONESTOPBIT; myDcb.Parity = NOPARITY; myDcb.fOutxCtsFlow = FALSE; myDcb.fOutxDsrFlow = FALSE; myDcb.fDsrSensitivity = FALSE; myDcb.fOutX = FALSE; myDcb.fInX = FALSE; myDcb.fRtsControl = RTS_CONTROL_ENABLE; myDcb.fDtrControl = DTR_CONTROL_ENABLE; if (!SetCommState( ComHandle, &myDcb )) {
printf("Can't set the state\n"); exit(1);
}
myTimeOuts.ReadIntervalTimeout = startingMilli; myTimeOuts.ReadTotalTimeoutMultiplier = 0; myTimeOuts.ReadTotalTimeoutConstant = 0; myTimeOuts.WriteTotalTimeoutMultiplier = 0; myTimeOuts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts( ComHandle, &myTimeOuts )) {
printf("Couldn't set the initial timeouts\n"); exit(1);
}
if (!(AllDoneEvent = CreateEvent( NULL, TRUE, FALSE, NULL ))) {
printf("Could not create the all done event\n"); exit(1);
}
if (!(WriteWaitEvent = CreateEvent( NULL, FALSE, FALSE, NULL ))) {
printf("Could not create the write wait event\n"); exit(1);
}
if (!(ProceedWithReads = CreateEvent( NULL, TRUE, TRUE, NULL ))) {
printf("Could not create the proceed with reads event\n"); exit(1);
}
if (!(ProceedWithNextWriteLoop = CreateEvent( NULL, TRUE, FALSE, NULL ))) {
printf("Could not create the proceed with writes event\n"); exit(1);
}
if (!(ReadOverLap.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ))) {
printf("Could not create the read event\n"); exit(1);
}
if (!(WriteOverLap.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ))) {
printf("Could not create the write event\n"); exit(1);
}
threadHandle = CreateThread( NULL, 0, ReadThread, 0, 0, &junk );
if (!threadHandle) {
printf("Couldn't create the thread\n"); exit(1);
}
currentMilli = startingMilli; while (currentMilli <= endingMilli) {
printf("Interval timeout test for %d milliseconds\n",currentMilli); for ( junk = 0; junk <= 9; junk++ ) {
//
// Wait for the read thread to say that it's ok to write.
//
WaitForSingleObject( WriteWaitEvent, INFINITE );
if (!WriteFile( ComHandle, &buff[0], 5, &numberActuallyWritten, &WriteOverLap )) {
if (GetLastError() != ERROR_IO_PENDING) {
printf("Write went bad\n"); exit(1);
}
GetOverlappedResult( ComHandle, &WriteOverLap, &numberActuallyWritten, TRUE );
}
}
currentMilli += 100; myTimeOuts.ReadIntervalTimeout = currentMilli; if (!SetCommTimeouts( ComHandle, &myTimeOuts )) {
printf("Couldn't set the new timeouts\n"); exit(1);
}
SetEvent(ProceedWithReads); WaitForSingleObject(ProceedWithNextWriteLoop,INFINITE);
}
SetEvent(AllDoneEvent); WaitForSingleObject(threadHandle,INFINITE);
return 1;
}
|