paddyc
asked on
Timer. Loop every 5ms
I want to set up a timer to send raw packets accross the network every 5ms( or quicker if possible ). I am using winpcap to send the packets as this bypasses the protocol stack and has less overhead. I was wondering what is the best way to set up a loop to get this kind of accuracy.
The following function is taking out of a book called Windows Graphics Programming.
inline unsigned __int64 GetCycleCount(void)
{
_asm _emit 0x0F;
_asm _emit 0x31;
}
This function returns RDTSC (Read Time Stamp Counter), which returns the number of clock cycles passed since the booting of the CPU.
On a Petium 200-Mhz machine, this has about a 5-nanosecond precision.
This function is not OS dependent, but it is machine dependent.
inline unsigned __int64 GetCycleCount(void)
{
_asm _emit 0x0F;
_asm _emit 0x31;
}
This function returns RDTSC (Read Time Stamp Counter), which returns the number of clock cycles passed since the booting of the CPU.
On a Petium 200-Mhz machine, this has about a 5-nanosecond precision.
This function is not OS dependent, but it is machine dependent.
ASKER
Windows XP.
It's a Win32 console based application.
Can you show me how to implement GetTickCount in c.
It's a Win32 console based application.
Can you show me how to implement GetTickCount in c.
DWORD StartTime;
StartTime = GetTickCount();
while(GetTickCount() < (StartTime + 5)); //Wait 5ms
StartTime = GetTickCount();
while(GetTickCount() < (StartTime + 5)); //Wait 5ms
ASKER
How can GetCycleCount allow me to call a function every 5ms?
Is there a way of starting a timer and then calling my function every 5ms. i.e. after 5ms, 10ms, 15ms.....
Is there a way of starting a timer and then calling my function every 5ms. i.e. after 5ms, 10ms, 15ms.....
ASKER
What type of resolution does GetTickCount have?
AFAIK, GetTickCount resolution is about 20 ms. You can use high-precision multimedia timer, for example, timeGetTime function.
ASKER
timeGetTime has a resolution of 2ms which is too large for my application.
PerformanceCounter() has a better resolution but I dont know how I would implement it.
PerformanceCounter() has a better resolution but I dont know how I would implement it.
In timeSetEvent function you can set required resolution, and it works with callback function.
This is code fragment which shows how to measure time using QueryPerformanceCounter:
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
__int64 nCalcTime; // ms
QueryPerformanceFrequency( &nFreq);
QueryPerformanceCounter(&n BeginTime) ;
// do something ...
QueryPerformanceCounter(&n EndTime);
nCalcTime = (nEndTime.QuadPart - m_nBeginTime.QuadPart) * 1000/m_nFreq.QuadPart;
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
__int64 nCalcTime; // ms
QueryPerformanceFrequency(
QueryPerformanceCounter(&n
// do something ...
QueryPerformanceCounter(&n
nCalcTime = (nEndTime.QuadPart - m_nBeginTime.QuadPart) * 1000/m_nFreq.QuadPart;
nCalcTime = (nEndTime.QuadPart - nBeginTime.QuadPart) * 1000/nFreq.QuadPart; // correction
ASKER
The above code checks how long something takes to complete.
I want to be able do something after a certain time has elapsed.
I want to be able do something after a certain time has elapsed.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
No matter what method you use, you will also need to give your process a higher priority to have your timer be accurate.
ASKER
Would I be able to call my function every 0.5ms with this function or would the accuracy be compromised?
How would I give my process a higher priority?
How would I give my process a higher priority?
>>Would I be able to call my function every 0.5ms with this function or would the accuracy be compromised?
Not 0.5ms
That is less then a ms
How are you starting your process?
What type of project do you have? Is it a console application or a Win32 windows application?
Not 0.5ms
That is less then a ms
How are you starting your process?
What type of project do you have? Is it a console application or a Win32 windows application?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It's a Win32 console application that's run from the command line.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
The GetTickCount() function is not accurate enough for my application.
The QueryPerformanceCounter() function is more accurate.
How would I create a 5ms loop (or smaller) using this counter?
The QueryPerformanceCounter() function is more accurate.
How would I create a 5ms loop (or smaller) using this counter?
You can set a timer of 5msec in the folowing manner. This function is written in HP unix.
#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long timeint()
{
clock_t start_time, end_time, query_time;
struct tms times_l; /*structure for times() function*/
start_time = times(×_l);
end_time = times(×_l);
query_time = (end_time-start_time);
return( (query_time*1000)/sysconf( _SC_CLK_TC K));
}
void main()
{
int dur;
for(int i=0; i<=50000;i++)
{
dur +=timeint();
if (dur>=10)
{
dur=0;
printf("reached timer interval\n");
//call your funtion here to send packet
}
}
}
#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long timeint()
{
clock_t start_time, end_time, query_time;
struct tms times_l; /*structure for times() function*/
start_time = times(×_l);
end_time = times(×_l);
query_time = (end_time-start_time);
return( (query_time*1000)/sysconf(
}
void main()
{
int dur;
for(int i=0; i<=50000;i++)
{
dur +=timeint();
if (dur>=10)
{
dur=0;
printf("reached timer interval\n");
//call your funtion here to send packet
}
}
}
ASKER
when I run the code the timeint() function returns 0 every time and so my function would never be run.
This is because your program is taking less than 5ms to complete.
you can change the validity of function by changeing for loop to an infiinite loop....so it will be called after every 5ms endlessly.
changes to be made are
Previous code:
for(int i=0; i<=50000;i++)
new code:
for(;;)
you can change the validity of function by changeing for loop to an infiinite loop....so it will be called after every 5ms endlessly.
changes to be made are
Previous code:
for(int i=0; i<=50000;i++)
new code:
for(;;)
ASKER
>> dur +=timeint();
>> if (dur>=10)
>> {
>> dur=0;
>> printf("reached timer interval\n");
>> //call your funtion here to send packet
dur never gets >=10 because timeint() always returns 0 so my function is always skipped.
>> if (dur>=10)
>> {
>> dur=0;
>> printf("reached timer interval\n");
>> //call your funtion here to send packet
dur never gets >=10 because timeint() always returns 0 so my function is always skipped.
You are missing the infinite for loop. so your whole program is taking less time. I have included a dummy function which it is calling after 2 seconds( to give you a clear view). You can adjust that time accordingly
#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long timeint()
{
clock_t start_time, end_time, query_time;
struct tms times_l; //structure for times() function
start_time = times(×_l);
end_time = times(×_l);
query_time = (end_time-start_time);
return( (query_time*1000)/sysconf( _SC_CLK_TC K));
}
void dummy()
{
printf("hi i am sending packet\n");
}
void main()
{
int dur;
for(;;)
{
dur +=timeint();
if (dur>=2000)
{
dur=0;
printf("reached timer interval\n");
//call your funtion here to send packet
dummy();
}
}
}
regards
-varun
#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long timeint()
{
clock_t start_time, end_time, query_time;
struct tms times_l; //structure for times() function
start_time = times(×_l);
end_time = times(×_l);
query_time = (end_time-start_time);
return( (query_time*1000)/sysconf(
}
void dummy()
{
printf("hi i am sending packet\n");
}
void main()
{
int dur;
for(;;)
{
dur +=timeint();
if (dur>=2000)
{
dur=0;
printf("reached timer interval\n");
//call your funtion here to send packet
dummy();
}
}
}
regards
-varun
All that example code will be of no use iff the OS takes away more time than you can tolerate. Please run my latency test program to see what kind of accuracy your particular OS and hardware can deliver.
The author wants the time resolution in msec and the CPU ticks are nowadays in megahertz.... so the purpose of the author is metby all means...
In windolws, you can try using GetTickCount API function.