11

I have a thread running on a Linux system which i need to execute in as accurate intervals as possbile. E.g. execute once every ms.

Currently this is done by creating a timer with

 timerfd_create(CLOCK_MONOTONIC, 0)

, and then passing the desired sleep time in a struct with

 timerfd_settime (fd, 0, &itval, NULL);

A blocking read call is performed on this timer which halts thread execution and reports lost wakeup calls.

The problem is that at higher frequencies, the system starts loosing deadlines, even though CPU usage is below 10%. I think this is due to the scheduler not waking the thread often enough to check the blocking call. Is there a command i can use to tell the scheduler to wake the thread at certain intervals as far as it is possble? Busy-waiting is a bad option since the system handles many other tasks.

Thank you.

K_scheduler
  • 143
  • 1
  • 4
  • 1
    Are you running this on the real-time scheduler? In my experience that should be good enough for intervals on the order of a millisecond, as long as your kernel doesn't have any badly-behaved drivers. (Of course, Linux isn't a specialist RTOS, and there's no guarantee that you'll never miss a deadline.) – Mike Seymour Jun 10 '11 at 14:58

5 Answers5

5

You need to get RT linux*, and then increase the RT priority of the process that you want to wake up at regular intervals.

Other then that, I do not see problems in your code, and if your process is not getting blocked, it should work fine.

(*) RT linux - an os with some real time scheduling patches applied.

BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • 1
    Thank you V Jo, i have thought about this as an option. At this moment in time i am locked to a normal Vanilla version, but i will look into this further on. On the other hand, if i do run an RT Linux version.. What guarantees do i have that the Scheduler will wake this thread at accurate intervals to check the blocking call? - There must be a more efficient safer way? – K_scheduler Jun 10 '11 at 14:00
  • @K_scheduler Depends on how good RT version you find. You have hard and soft scheduling guaranties, and it all depends on the implementation. I think on hard guaranties the error is bellow 1 ms (not sure tho) – BЈовић Jun 10 '11 at 14:07
  • 3
    as an example, check https://rt.wiki.kernel.org/index.php/CONFIG_PREEMPT_RT_Patch – stefaanv Jun 10 '11 at 14:19
  • @K_scheduler: a vanilla kernel should be good enough, if you don't need a guarantee that you'll never miss a deadline, as long as put this thread on the real-time scheduler. – Mike Seymour Jun 10 '11 at 15:00
2

One way to reduce scheduler latency is to run your process using the realtime scheduler such as SCHED_FIFO. See sched_setscheduler .

This will generally improve latency a lot, but still theres little guarantee, to further reduce latency spikes, you'll need to move to the realtime brance of linux, or a realtime OS such as VxWorks, RTEMS or QNX.

nos
  • 223,662
  • 58
  • 417
  • 506
1

You won't be able to do what you want unless you run it on an actual "Real Time OS".

Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
1

If this is only Linux for x86 system I would choose HPET timer. I think all modern PCs has this hardware timer build in and it is very, very accurate. I allow you to define callback that will be called every millisecond and in this callback you can do your calculations (if they are simple) or just trigger other thread work using some synchronization object (conditional variable for example) Here is some example how to use this timer http://blog.fpmurphy.com/2009/07/linux-hpet-support.html

Zuljin
  • 2,612
  • 17
  • 14
1

Along with other advice such as setting the scheduling class to SCHED_FIFO, you will need to use a Linux kernel compiled with a high enough tick rate that it can meet your deadline.

For example, a kernel compiled with CONFIG_HZ of 100 or 250 Hz (timer interrupts per second) can never respond to timer events faster than that.

You must also set your timer to be just a little bit faster than you actually need, because timers are allowed to go beyond their requested time but never expire early, this will give you better results. If you need 1 ms, then I'd recommend asking for 999 us instead.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131