On Tue, Apr 21, 2015 at 9:38 AM, Saúl Ibarra Corretgé <[email protected]> wrote: > On 04/20/2015 04:01 PM, Andrius Bentkus wrote: >> While toying around with libuv I have found out that the epoll timer has >> a resolution of only a second which creates a drift. >> >> If we do something like >> >> ```js >> var count = 0; >> var last = count; >> >> setInterval(function () { >> count++; >> }, 1); // every millisecond >> >> setInterval(function () { >> console.log(count - last); >> last = count; >> }, 1000); // after a second >> ``` >> >> With libuv (this is nodejs code, but the same would hold true for >> C/libuv code) we get < 1000 events per second. On my machine its around >> ~923 events. >> >> Now this is impossible to solve with epoll having a timeout based on >> milliseconds and not nanoseconds, but I just wanted to post this: >> https://github.com/famz/linux/tree/epoll_pwait1 >> >> This patch introduces an epoll api which works on nano second resolution >> and would allow us to get the thing running sufficiently fine graind. >> The author wants that feature to get into the kernel for qemu. >> >> Here is the entire discussion on the linux kernel mailing list >> http://thread.gmane.org/gmane.linux.kernel.api/8250 >> >> I just wanted to post this so we would keep a look out for when the >> feature hits the kernel >> > > Nice! > > When drafting the uv_timeout API someone (Ben IIRC) told me that we > could make the timeout a double, and thus support sub-millisecond > precision, where possible. AFAIK we could have sub-millisecond precision > if we use a timerfd instead of passing the timeout to epoll_wait/pwait. > We'd arm a single timerfd per loop, witht he value of the closest timer, > and add it to the epoll set, and then we'd call epoll_wait/pwait with a > NULL timeout. > > I'm not sure if there are limitations I'm not aware of here, but that > could be a start. The new epoll API could be supported as well, but > before that the user facing APIs need to support specifying > sub-millisecond precision.
That was me, yes. :-) There is a minor complication in that the linux kernel has a concept of 'timer slack'; to increase throughput, the kernel tries to coalesce timer events by postponing process wake-up. The default slack is 50 microseconds, or 1/20,000th of a second; probably fast enough for most applications. You can disable it on a per-thread basis with `prctl(PR_SET_TIMERSLACK, 1)`. Zero resets it. However, the slack also affects the granularity of the futex() system call, in turn affecting library functions that are built on top of it, like pthread_cond_timedwait() and sem_timedwait(). Depending on your viewpoint, that may or may not be a good thing. -- You received this message because you are subscribed to the Google Groups "libuv" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/libuv. For more options, visit https://groups.google.com/d/optout.
