Link to home
Start Free TrialLog in
Avatar of paddyc
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.
Avatar of Axter
Axter
Flag of United States of America image

What OS are you using?

In windolws, you can try using GetTickCount API function.
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.
Avatar of paddyc
paddyc

ASKER

Windows XP.
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
Avatar of paddyc

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.....
Avatar of paddyc

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.
Avatar of paddyc

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.
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(&nBeginTime);

    // do something ...

    QueryPerformanceCounter(&nEndTime);
    nCalcTime = (nEndTime.QuadPart - m_nBeginTime.QuadPart) * 1000/m_nFreq.QuadPart;
nCalcTime = (nEndTime.QuadPart - nBeginTime.QuadPart) * 1000/nFreq.QuadPart;   // correction
Avatar of paddyc

ASKER

The above code checks how long something takes to complete.

I want to be able do something after a certain time has elapsed.
SOLUTION
Avatar of Axter
Axter
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No matter what method you use, you will also need to give your process a higher priority to have your timer be accurate.
Avatar of paddyc

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?
>>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?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of paddyc

ASKER

It's a Win32 console application that's run from the command line.

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of paddyc

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?
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(&times_l);
      end_time = times(&times_l);
      query_time = (end_time-start_time);
    return( (query_time*1000)/sysconf(_SC_CLK_TCK));

}
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
            
     }
}

}
Avatar of paddyc

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(;;)
Avatar of paddyc

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.
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(&times_l);
      end_time = times(&times_l);
      query_time = (end_time-start_time);
    return( (query_time*1000)/sysconf(_SC_CLK_TCK));

}

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...