3

epoll_wait, select and poll functions all provide a timeout. However with epoll, it's at a large resolution of 1ms. Select & ppoll are the only one providing sub-millisecond timeout.

That would mean doing other things at 1ms intervals at best. I could do a lot of other things within 1ms on a modern CPU.

So to do other things more often than 1ms I actually have to provide a timeout of zero (essentially disabling it). And I'd probably add my own usleep somewhere in the main loop to stop it chewing up too much CPU.

So the question is, why is the timeout in milli's when I would think clearly there is a case for a higher resolution timeout.

hookenz
  • 36,432
  • 45
  • 177
  • 286
  • This article provides more information on the timing resolution of select(), poll() and epoll_wait() and their interaction with the kernel. I recommend reading it. http://lwn.net/Articles/296578/ – Andrew Jessop Feb 01 '13 at 15:48
  • There was a patch proposed to fix this, but it seems it was abandoned by the author after this comment: https://lkml.org/lkml/2015/3/13/385 – Tim Rae Jul 10 '18 at 12:31

3 Answers3

13

Since you are on Linux, instead of providing a zero timeout value and manually usleeeping in the loop body, you could simply use the timerfd API. This essentially lets you create a timer (with a resolution finer than 1ms) associated with a file descriptor, which you can add to the set of monitored descriptors.

2

In Linux 5.11, an epoll_pwait2 API has been added, which uses a struct timespec as timeout. This means you can now wait using nanoseconds precision.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Emil
  • 16,784
  • 2
  • 41
  • 52
2

The epoll_wait interface just inherited a timeout measured in milliseconds from poll. While it doesn't make sense to poll for less than a millisecond, because of the overhead of adding the calling thread to all the wait sets, it does make sense for epoll_wait. A call to epoll_wait doesn't require ever putting the calling thread onto more than one wait set, the calling overhead is very low, and it could make sense, on very rare occasions, to block for less than a millisecond.

I'd recommend just using a timing thread. Most of what you would want to do can just be done in that timing thread, so you won't need to break out of epoll_wait. If you do need to make a thread return from epoll_wait, just send a byte to a pipe that thread is polling and the wait will terminate.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278