millisecond sleep for linux

jgreaves
jgreaves used Ask the Experts™
on
I am looking for a millisecond acurate sleep for linux

similar to
Irmx sysrtsleep()
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
If delay is Ok for you, you can use:
#include <linux/delay.h>
void mdelay( unsigned long milliseconds );
void udelay( unsigned long microseconds );

Note: it will be delay, not sleep.
Commented:
I believe the question concerns a user space program.  udelay() and mdelay() are internal Linux kernel services.

From user space, you want nanosleeep().  There's also the older usleep(), but compatibility is about the only valid reason to use it.

These are not all that accurate, though.  You can specify a sleep time down to the microsecond, but Linux process scheduling can keep you asleep considerably longer than you requested.  If you use the proper realtime scheduling priority, they are probably pretty accurate.

Commented:
accurate to the what millisecond?  usleep can server you in micros, and you do the math etc etc etc.  as long as you are talking 10+ milliseconds, it should be real "REAL" close acuraccy to the milliseconds. If you are looking for microseconds accuracy, use real time linux www.rtl.org, the kernel is modified to real time processing.
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Glibc has a bunch of high res time functions and structures in timex.h.  Check out the glibc manual at GNU.org for the details.  Maybe one of the functions will meet your needs.

Commented:
Use select(). This is portable over most if not
all UNIX like platforms. As already stated by the others
posters the resolution is limited by the scheduler's
resolution (abt. 10ms in Linux).

e.g:

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int waitms(int millisecs) {

  fd_set dummy;
  struct timeval toWait;

  FD_ZERO(&dummy);
  toWait.tv_sec = millisecs / 1000;
  toWait.tv_usec = (millisecs % 1000) * 1000;

  return select(0, &dummy, NULL, NULL, &toWait);

}

Commented:
If you are:
  using scheduling policy SCHED_FIFO or SCHED_RR (see "man sched_setparam")
  sleeping for <= 2ms
then use nanosleep. The kernel will busy-wait rather than rescheduling the process, so it should be accurate enough.

You can only usefully do this if the process is the only one running since you need to ensure that you aren't rescheduled immediately before or after the nanosleep.

Commented:
For long time accurate sleep:

0. your task should have root privileges.

1. make sure your application pages locked in RAM (mlock or mlockall).

2. Set real-time scheduling (SHED_RR or SCHED_FIFO policy) and high priority using sched_setscheduler.

3. Let process sleep requred time minus 1/HZ (usually 10ms) using nanosleep.

4. Check the remaining time to sleep using gettimeofday (with tz == NULL).

5. Sleep the rest of time using several short nanosleep calls (<=2ms).

Of course, it is not the perfect method, use RTLinux for most accuracy (http://fsmlabs.com/community/) or any other hard real-time OS.

Andrey

Commented:
I pretty much see everybody on the same page, and whatever you do, do Not use select.  Select is pretty powerful when it comes to listening to files or sockets, and will even do your timeout,BUT, Biiiig BUT.  If you receive an interrup, any type of signal, select will exit with an error code.
to determine where an error occured, one should check errno and see if it was just a signal, SIGCHLD, empty all sets and back. This is lots of time, LOTS if you are looking for ms accuracy.  

Sapa  if my mind is Not playing tricks on me, One hz is a second.

Commented:
garboua:

1. you can block all signals before entering select(...), but in any case select does not provide enough accuracy. It use 1/HZ granularity.

2. HZ is not One Herz in this context. It is macros defined in /usr/include/asm/param.h and usually it equals 100. It means the frequency of timer interrupts in this system.

Commented:
I he's got hard real time requirements, vanilla linux
isn't the platform to use, as already pointed out by garboua.
I don't see how any userland program can sleep with better than 1/HZ accurary (unless using SCHED_RR) since that is the timer interrupt frequency which in turn determines how often the OS is guaranteed to switch into kernel mode and schedule a waiting/sleeping process for execution.

I doesn't matter that you 'loose' some time when checking
for an interrupted sleep, if the accuracy is only about 10ms.

nanosleep with SCHED_RR is the best method, if you are sure
that the program will only run on UNIXes having that function.

Commented:
Sleeps less than the clock period make sense when you're using them as a minimum delay rather than an absolute delay.  E.g. "don't bother running me again until at least 2 ms from now".  If there happens to be a clock tick or other interrupt 3 ms from now, it's OK for you to run.  If there isn't one for another 10 ms, that's OK too.

Also, it's not a very substantial change to conventional Linux to make the clock period less than 100 ms.

Commented:
I was told this over the past week, but it is not 100% confirmed. there is a patch of realtime linux that would create a "software driven second auxilary clock." if this is correct, then it could be clocked at a higher rate, and you can use it to generate your interrupts and use your scheduler to use it VS onboard system clock.  

Commented:
i have a pice of code in ANSI C, this is basic but useful.

#include <time.h>
void Sleep(clock_t wait)
{
        clock_t goal;
        goal = wait * (CLOCKS_PER_SEC / 1000);
        while( goal >=  clock())
                ;
}

I tooke the amouts of clock cycles per seconds, so in time in milliseconds I diveded by 1000 so i count cycles until I get my amount of time.
thx.
Fisu

Author

Commented:
used usleep();  iy worked well enough thanks

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial