… | |
… | |
221 | /* |
221 | /* |
222 | * This is used to avoid floating point rounding problems. |
222 | * This is used to avoid floating point rounding problems. |
223 | * It is added to ev_rt_now when scheduling periodics |
223 | * It is added to ev_rt_now when scheduling periodics |
224 | * to ensure progress, time-wise, even when rounding |
224 | * to ensure progress, time-wise, even when rounding |
225 | * errors are against us. |
225 | * errors are against us. |
226 | * This value is good at least till the year 4000 |
226 | * This value is good at least till the year 4000. |
227 | * and intervals up to 20 years. |
|
|
228 | * Better solutions welcome. |
227 | * Better solutions welcome. |
229 | */ |
228 | */ |
230 | #define TIME_EPSILON 0.0001220703125 /* 1/8192 */ |
229 | #define TIME_EPSILON 0.0001220703125 /* 1/8192 */ |
231 | |
230 | |
232 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
231 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
… | |
… | |
1248 | assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > ev_rt_now)); |
1247 | assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > ev_rt_now)); |
1249 | downheap ((WT *)periodics, periodiccnt, 0); |
1248 | downheap ((WT *)periodics, periodiccnt, 0); |
1250 | } |
1249 | } |
1251 | else if (w->interval) |
1250 | else if (w->interval) |
1252 | { |
1251 | { |
1253 | ((WT)w)->at = w->offset + floor ((ev_rt_now + TIME_EPSILON - w->offset) / w->interval + 1.) * w->interval; |
1252 | ((WT)w)->at = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval; |
|
|
1253 | if (((WT)w)->at - ev_rt_now <= TIME_EPSILON) ((WT)w)->at += w->interval; |
1254 | assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > ev_rt_now)); |
1254 | assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > ev_rt_now)); |
1255 | downheap ((WT *)periodics, periodiccnt, 0); |
1255 | downheap ((WT *)periodics, periodiccnt, 0); |
1256 | } |
1256 | } |
1257 | else |
1257 | else |
1258 | ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ |
1258 | ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ |
… | |
… | |
1371 | if (expect_false (mn_now > ev_rt_now || mn_now < ev_rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP)) |
1371 | if (expect_false (mn_now > ev_rt_now || mn_now < ev_rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP)) |
1372 | { |
1372 | { |
1373 | #if EV_PERIODIC_ENABLE |
1373 | #if EV_PERIODIC_ENABLE |
1374 | periodics_reschedule (EV_A); |
1374 | periodics_reschedule (EV_A); |
1375 | #endif |
1375 | #endif |
1376 | |
|
|
1377 | /* adjust timers. this is easy, as the offset is the same for all of them */ |
1376 | /* adjust timers. this is easy, as the offset is the same for all of them */ |
1378 | for (i = 0; i < timercnt; ++i) |
1377 | for (i = 0; i < timercnt; ++i) |
1379 | ((WT)timers [i])->at += ev_rt_now - mn_now; |
1378 | ((WT)timers [i])->at += ev_rt_now - mn_now; |
1380 | } |
1379 | } |
1381 | |
1380 | |