Hello,

I tried to use libuv on Linux for an application that require a precise 
periodicity. I observed that uv_timer_start(, ,100, 100) make the 
repetitive epoll() always wait a bit more than 100ms, regardless of the 
callback function execution time (strace -T):
epoll_wait(5, {}, 1024, 99)             = 0 <0.099287>  <= First epoll() 
wait 99.287ms
sync()                                  = 0 <0.054469>
epoll_wait(5, {}, 1024, 100)            = 0 <0.100211>  <= Second epoll() 
wait 100.211ms
sync()                                  = 0 <0.040866>
epoll_wait(5, {}, 1024, 100)            = 0 <0.100207>  <===
sync()                                  = 0 <0.046870>
epoll_wait(5, {}, 1024, 100)            = 0 <0.100214>  <===
sync()                                  = 0 <0.043035>
epoll_wait(5, {}, 1024, 100)            = 0 <0.100139>  <===
I use the sync() in the callback to very simply add a execution of about 
from 40ms to 50ms on the test machine, the final application is more 
complex than that, this is just to keep the example as simple as possible. 
After the first epoll(), all epoll() have a similar length of a bit more 
that 100ms. This already too long delay is in addition to the delay of the 
sync() call. In fine, the period of this example is between 140ms and 150ms 
instead of the expected 100ms. If I filter the sync() call time I get this 
(strace -tt):
00:31:27.960802 sync()                  = 0
00:31:28.106703 sync()                  = 0
00:31:28.250530 sync()                  = 0
00:31:28.391060 sync()                  = 0
00:31:28.529861 sync()                  = 0
00:31:28.669751 sync()                  = 0
00:31:28.810477 sync()                  = 0
00:31:28.949302 sync()                  = 0
The jitter of the sync() call time is very big, probably equal to the 
callback execution time.

I tested timerfd_create() on the same machine with a loop of read() on the 
timerfd file and sync(). The result is very different (strace -T):
timerfd_create(CLOCK_MONOTONIC, 0)      = 9 <0.000013>
timerfd_settime(9, 0, {it_interval={0, 100000000}, it_value={0, 100000000}}, 
NULL) = 0 <0.000014>
read(9, "\1\0\0\0\0\0\0\0", 8)          = 8 <0.100138>  <== First read() on 
timerd fd file wait 100.138ms
sync()                                  = 0 <0.053847>
read(9, "\1\0\0\0\0\0\0\0", 8)          = 8 <0.045944>  <= Second read() 
wait 45.944ms
sync()                                  = 0 <0.047778>
read(9, "\1\0\0\0\0\0\0\0", 8)          = 8 <0.051987>  <===
sync()                                  = 0 <0.046731>
read(9, "\1\0\0\0\0\0\0\0", 8)          = 8 <0.053102>  <===
sync()                                  = 0 <0.044829>
read(9, "\1\0\0\0\0\0\0\0", 8)          = 8 <0.055018>  <===
The read() delay compensate exactly the sync() delay to make a periodicity 
of exactly 100ms. If I filter the sync() call time I get this (strace -tt):
00:47:23.687205 sync()                  = 0
00:47:23.787220 sync()                  = 0
00:47:23.887393 sync()                  = 0
00:47:23.987276 sync()                  = 0
00:47:24.087210 sync()                  = 0
00:47:24.187164 sync()                  = 0
00:47:24.287242 sync()                  = 0
00:47:24.387330 sync()                  = 0
00:47:24.487286 sync()                  = 0
00:47:24.587181 sync()                  = 0
00:47:24.687237 sync()                  = 0
The jitter of the sync() call time is smaller than 1ms, something that the 
current libuv is unable to do.

I have two questions:
1) is there anything that would prevent libuv from using timerfd_settime() 
on Linux ?
2) Is there any motivation to do that ?

Best Regards,

Jean-Christian

-- 
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.

Reply via email to