Quote:Original post by Katie
The problem with using user-space solutions such as epoll/select/timerfd etc is that while they will work, they're not actually a "real-time" solution in that service is not guaranteed.
Your process *could* be suspended for (essentially) arbitrary amounts of time depending on what other things are happening in the system. For example; inside those system calls, the kernel may go do dirty page flushes for other processes. And it may wait on those page writes completing before returning.
This is the essential difference between "real-time" and "multi-tasking" systems -- a real-time environment guarantees a service delivery window.
Depending on what you're doing, this may or may not be acceptable, but you need to know that it's happening.
Apart from that, the advice to use multiple timerfds and run an epoll gather/dispatch loop is probably the right way to go. It's fairly easy to build a service object which creates a timerfd and hooks it into the epoll set storing a this pointer into the epoll userdata. Inherit from this implementing your service method. The main loop calls the epoll, gathers the event and just calls the service vmethod through the userdata pointer.
There is a single "gotcha" with this -- if you delete an object, it may already have been signalled and hence stored into the event queue. So you need to keep an eye out for stale pointers. Apart from that, the epoll sets are all thread-safe (because they're kernel internals) so you don't need to worry about that stuff.
Very useful information. I am actually thinking about ordering a customerized CSP (chip support package) from Wind River so I can get a "real-time" kernel instead of "multi-tasking" one. I think I should add the following into the requirement of CSP: A easy-to-use API to start a timer and get software interrupt or event; The kernel should be real-time 1000Hz one which means it can generate the software interrupt or event for at least every 1ms. Does the requirements make sense?
I am also considering epoll/epoll_wait/select/timerfd, it may become an elegant solution too, since I think my application doesn't have strict real-time requirement. I need some tests though. Thank you for pointing out the "gotcha'.