?
Solved

Timer. Loop every 5ms

Posted on 2005-03-01
28
Medium Priority
?
374 Views
Last Modified: 2012-05-05
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.
0
Comment
Question by:paddyc
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 6
  • 4
  • +2
28 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 13428254
What OS are you using?

In windolws, you can try using GetTickCount API function.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13428262
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.
0
 

Author Comment

by:paddyc
ID: 13428279
Windows XP.
It's a Win32 console based application.

Can you show me how to implement GetTickCount in c.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 30

Expert Comment

by:Axter
ID: 13428323
DWORD StartTime;

StartTime = GetTickCount();
while(GetTickCount() < (StartTime + 5)); //Wait 5ms
0
 

Author Comment

by:paddyc
ID: 13428328
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.....
0
 

Author Comment

by:paddyc
ID: 13428333
What type of resolution does GetTickCount have?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13428370
AFAIK, GetTickCount resolution is about 20 ms. You can use high-precision multimedia timer, for example, timeGetTime function.
0
 

Author Comment

by:paddyc
ID: 13428451
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.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13428490
In timeSetEvent function you can set required resolution, and it works with callback function.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13428537
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;
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 13428545
nCalcTime = (nEndTime.QuadPart - nBeginTime.QuadPart) * 1000/nFreq.QuadPart;   // correction
0
 

Author Comment

by:paddyc
ID: 13428598
The above code checks how long something takes to complete.

I want to be able do something after a certain time has elapsed.
0
 
LVL 30

Assisted Solution

by:Axter
Axter earned 75 total points
ID: 13428752
>>Is there a way of starting a timer and then calling my function every 5ms. i.e. after 5ms, 10ms, 15ms.....

Try the following:

DWORD StartTime;

for(;;)
{
     StartTime = GetTickCount();
     while(GetTickCount() < (StartTime + 5)); //Wait 5ms
     YourFunctionCall();
}

The above should call your function every 5ms

FYI: From MSDN documents:
The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer. To obtain the system timer resolution, use the GetSystemTimeAdjustment function.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13428767
No matter what method you use, you will also need to give your process a higher priority to have your timer be accurate.
0
 

Author Comment

by:paddyc
ID: 13428875
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?
0
 
LVL 30

Expert Comment

by:Axter
ID: 13429810
>>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?
0
 
LVL 22

Accepted Solution

by:
grg99 earned 300 total points
ID: 13429878
Ah, Windows was not designed as a real-time system.  It's barely usable as a human-time system.  The OS and device drivers take big chunks out of your CPU time, from microseconds to good fractions of a second.

The situation is a lot better on a multi-CPU system-- if you do a bunch of "setProcessorAffinity()" calls you can kinda coerce Windows into just hogging one CPU, leaving you a lot of time on the other one.  No guarantees though.

0
 

Author Comment

by:paddyc
ID: 13431739
It's a Win32 console application that's run from the command line.

0
 
LVL 22

Assisted Solution

by:grg99
grg99 earned 300 total points
ID: 13432502
Well, time it yourself and see.   Call that RDTSC function above with the 0Fh 31h opcodes.  Compute the time since the last call.  Keep a histogram of the latency between calls.  Something like:

#define TicksPerUsec 200    // 200MHz clock

int histo[50000];   // microseconds of latency

for( i=0; i< 50000; i++ ) histo[i] = 0;

Prev = GetTSC();
for( i=1; i< 100000; i++ ) {
   Elap = ( GetTSC() - Prev ) / TicksPerUSec;;
   if( Elap > 0 && Elap < 50000 )  histo[ Elap ]++; }
}


 
0
 

Author Comment

by:paddyc
ID: 13433277
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?
0
 

Expert Comment

by:vashukumar
ID: 13437580
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
            
     }
}

}
0
 

Author Comment

by:paddyc
ID: 13438218
when I run the code the timeint() function returns 0 every time and so my function would never be run.
0
 

Expert Comment

by:vashukumar
ID: 13446639
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(;;)
0
 

Author Comment

by:paddyc
ID: 13447710
>>     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.
0
 

Expert Comment

by:vashukumar
ID: 13447995
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
0
 
LVL 22

Expert Comment

by:grg99
ID: 13448087
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.

0
 

Expert Comment

by:vashukumar
ID: 13456066
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...
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
Suggested Courses
Course of the Month14 days, 18 hours left to enroll

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question