… | |
… | |
57 | # endif |
57 | # endif |
58 | # ifndef EV_USE_MONOTONIC |
58 | # ifndef EV_USE_MONOTONIC |
59 | # define EV_USE_MONOTONIC 1 |
59 | # define EV_USE_MONOTONIC 1 |
60 | # endif |
60 | # endif |
61 | # endif |
61 | # endif |
|
|
62 | # elif !defined(EV_USE_CLOCK_SYSCALL) |
|
|
63 | # define EV_USE_CLOCK_SYSCALL 0 |
62 | # endif |
64 | # endif |
63 | |
65 | |
64 | # if HAVE_CLOCK_GETTIME |
66 | # if HAVE_CLOCK_GETTIME |
65 | # ifndef EV_USE_MONOTONIC |
67 | # ifndef EV_USE_MONOTONIC |
66 | # define EV_USE_MONOTONIC 1 |
68 | # define EV_USE_MONOTONIC 1 |
… | |
… | |
282 | |
284 | |
283 | #ifndef EV_HEAP_CACHE_AT |
285 | #ifndef EV_HEAP_CACHE_AT |
284 | # define EV_HEAP_CACHE_AT !EV_MINIMAL |
286 | # define EV_HEAP_CACHE_AT !EV_MINIMAL |
285 | #endif |
287 | #endif |
286 | |
288 | |
|
|
289 | /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */ |
|
|
290 | /* which makes programs even slower. might work on other unices, too. */ |
|
|
291 | #if EV_USE_CLOCK_SYSCALL |
|
|
292 | # include <syscall.h> |
|
|
293 | # ifdef SYS_clock_gettime |
|
|
294 | # define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) |
|
|
295 | # undef EV_USE_MONOTONIC |
|
|
296 | # define EV_USE_MONOTONIC 1 |
|
|
297 | # else |
|
|
298 | # undef EV_USE_CLOCK_SYSCALL |
|
|
299 | # define EV_USE_CLOCK_SYSCALL 0 |
|
|
300 | # endif |
|
|
301 | #endif |
|
|
302 | |
287 | /* this block fixes any misconfiguration where we know we run into trouble otherwise */ |
303 | /* this block fixes any misconfiguration where we know we run into trouble otherwise */ |
288 | |
304 | |
289 | #ifndef CLOCK_MONOTONIC |
305 | #ifndef CLOCK_MONOTONIC |
290 | # undef EV_USE_MONOTONIC |
306 | # undef EV_USE_MONOTONIC |
291 | # define EV_USE_MONOTONIC 0 |
307 | # define EV_USE_MONOTONIC 0 |
… | |
… | |
320 | |
336 | |
321 | #if EV_SELECT_IS_WINSOCKET |
337 | #if EV_SELECT_IS_WINSOCKET |
322 | # include <winsock.h> |
338 | # include <winsock.h> |
323 | #endif |
339 | #endif |
324 | |
340 | |
325 | /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */ |
|
|
326 | /* which makes programs even slower. might work on other unices, too. */ |
|
|
327 | #if EV_USE_CLOCK_SYSCALL |
|
|
328 | # include <syscall.h> |
|
|
329 | # define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) |
|
|
330 | # undef EV_USE_MONOTONIC |
|
|
331 | # define EV_USE_MONOTONIC 1 |
|
|
332 | #endif |
|
|
333 | |
|
|
334 | #if EV_USE_EVENTFD |
341 | #if EV_USE_EVENTFD |
335 | /* our minimum requirement is glibc 2.7 which has the stub, but not the header */ |
342 | /* our minimum requirement is glibc 2.7 which has the stub, but not the header */ |
336 | # include <stdint.h> |
343 | # include <stdint.h> |
337 | # ifdef __cplusplus |
344 | # ifdef __cplusplus |
338 | extern "C" { |
345 | extern "C" { |
… | |
… | |
384 | # define inline_speed static noinline |
391 | # define inline_speed static noinline |
385 | #else |
392 | #else |
386 | # define inline_speed static inline |
393 | # define inline_speed static inline |
387 | #endif |
394 | #endif |
388 | |
395 | |
389 | #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) |
396 | #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) |
|
|
397 | |
|
|
398 | #if EV_MINPRI == EV_MAXPRI |
|
|
399 | # define ABSPRI(w) (((W)w), 0) |
|
|
400 | #else |
390 | #define ABSPRI(w) (((W)w)->priority - EV_MINPRI) |
401 | # define ABSPRI(w) (((W)w)->priority - EV_MINPRI) |
|
|
402 | #endif |
391 | |
403 | |
392 | #define EMPTY /* required for microsofts broken pseudo-c compiler */ |
404 | #define EMPTY /* required for microsofts broken pseudo-c compiler */ |
393 | #define EMPTY2(a,b) /* used to suppress some warnings */ |
405 | #define EMPTY2(a,b) /* used to suppress some warnings */ |
394 | |
406 | |
395 | typedef ev_watcher *W; |
407 | typedef ev_watcher *W; |
… | |
… | |
557 | |
569 | |
558 | #endif |
570 | #endif |
559 | |
571 | |
560 | /*****************************************************************************/ |
572 | /*****************************************************************************/ |
561 | |
573 | |
|
|
574 | #ifndef EV_HAVE_EV_TIME |
562 | ev_tstamp |
575 | ev_tstamp |
563 | ev_time (void) |
576 | ev_time (void) |
564 | { |
577 | { |
565 | #if EV_USE_REALTIME |
578 | #if EV_USE_REALTIME |
566 | if (expect_true (have_realtime)) |
579 | if (expect_true (have_realtime)) |
… | |
… | |
573 | |
586 | |
574 | struct timeval tv; |
587 | struct timeval tv; |
575 | gettimeofday (&tv, 0); |
588 | gettimeofday (&tv, 0); |
576 | return tv.tv_sec + tv.tv_usec * 1e-6; |
589 | return tv.tv_sec + tv.tv_usec * 1e-6; |
577 | } |
590 | } |
|
|
591 | #endif |
578 | |
592 | |
579 | inline_size ev_tstamp |
593 | inline_size ev_tstamp |
580 | get_clock (void) |
594 | get_clock (void) |
581 | { |
595 | { |
582 | #if EV_USE_MONOTONIC |
596 | #if EV_USE_MONOTONIC |
… | |
… | |
618 | |
632 | |
619 | tv.tv_sec = (time_t)delay; |
633 | tv.tv_sec = (time_t)delay; |
620 | tv.tv_usec = (long)((delay - (ev_tstamp)(tv.tv_sec)) * 1e6); |
634 | tv.tv_usec = (long)((delay - (ev_tstamp)(tv.tv_sec)) * 1e6); |
621 | |
635 | |
622 | /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ |
636 | /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ |
623 | /* somehting nto guaranteed by newer posix versions, but guaranteed */ |
637 | /* somehting not guaranteed by newer posix versions, but guaranteed */ |
624 | /* by older ones */ |
638 | /* by older ones */ |
625 | select (0, 0, 0, 0, &tv); |
639 | select (0, 0, 0, 0, &tv); |
626 | #endif |
640 | #endif |
627 | } |
641 | } |
628 | } |
642 | } |
… | |
… | |
1349 | ev_loop_count (EV_P) |
1363 | ev_loop_count (EV_P) |
1350 | { |
1364 | { |
1351 | return loop_count; |
1365 | return loop_count; |
1352 | } |
1366 | } |
1353 | |
1367 | |
|
|
1368 | unsigned int |
|
|
1369 | ev_loop_depth (EV_P) |
|
|
1370 | { |
|
|
1371 | return loop_depth; |
|
|
1372 | } |
|
|
1373 | |
1354 | void |
1374 | void |
1355 | ev_set_io_collect_interval (EV_P_ ev_tstamp interval) |
1375 | ev_set_io_collect_interval (EV_P_ ev_tstamp interval) |
1356 | { |
1376 | { |
1357 | io_blocktime = interval; |
1377 | io_blocktime = interval; |
1358 | } |
1378 | } |
… | |
… | |
1391 | |
1411 | |
1392 | ev_rt_now = ev_time (); |
1412 | ev_rt_now = ev_time (); |
1393 | mn_now = get_clock (); |
1413 | mn_now = get_clock (); |
1394 | now_floor = mn_now; |
1414 | now_floor = mn_now; |
1395 | rtmn_diff = ev_rt_now - mn_now; |
1415 | rtmn_diff = ev_rt_now - mn_now; |
|
|
1416 | invoke_cb = ev_invoke_pending; |
1396 | |
1417 | |
1397 | io_blocktime = 0.; |
1418 | io_blocktime = 0.; |
1398 | timeout_blocktime = 0.; |
1419 | timeout_blocktime = 0.; |
1399 | backend = 0; |
1420 | backend = 0; |
1400 | backend_fd = -1; |
1421 | backend_fd = -1; |
… | |
… | |
1765 | ev_invoke (EV_P_ void *w, int revents) |
1786 | ev_invoke (EV_P_ void *w, int revents) |
1766 | { |
1787 | { |
1767 | EV_CB_INVOKE ((W)w, revents); |
1788 | EV_CB_INVOKE ((W)w, revents); |
1768 | } |
1789 | } |
1769 | |
1790 | |
1770 | inline_speed void |
1791 | void |
1771 | call_pending (EV_P) |
1792 | ev_invoke_pending (EV_P) |
1772 | { |
1793 | { |
1773 | int pri; |
1794 | int pri; |
1774 | |
1795 | |
1775 | for (pri = NUMPRI; pri--; ) |
1796 | for (pri = NUMPRI; pri--; ) |
1776 | while (pendingcnt [pri]) |
1797 | while (pendingcnt [pri]) |
… | |
… | |
2011 | |
2032 | |
2012 | mn_now = ev_rt_now; |
2033 | mn_now = ev_rt_now; |
2013 | } |
2034 | } |
2014 | } |
2035 | } |
2015 | |
2036 | |
2016 | static int loop_done; |
|
|
2017 | |
|
|
2018 | void |
2037 | void |
2019 | ev_loop (EV_P_ int flags) |
2038 | ev_loop (EV_P_ int flags) |
2020 | { |
2039 | { |
|
|
2040 | ++loop_depth; |
|
|
2041 | |
2021 | loop_done = EVUNLOOP_CANCEL; |
2042 | loop_done = EVUNLOOP_CANCEL; |
2022 | |
2043 | |
2023 | call_pending (EV_A); /* in case we recurse, ensure ordering stays nice and clean */ |
2044 | invoke_cb (EV_A); /* in case we recurse, ensure ordering stays nice and clean */ |
2024 | |
2045 | |
2025 | do |
2046 | do |
2026 | { |
2047 | { |
2027 | #if EV_VERIFY >= 2 |
2048 | #if EV_VERIFY >= 2 |
2028 | ev_loop_verify (EV_A); |
2049 | ev_loop_verify (EV_A); |
… | |
… | |
2041 | /* we might have forked, so queue fork handlers */ |
2062 | /* we might have forked, so queue fork handlers */ |
2042 | if (expect_false (postfork)) |
2063 | if (expect_false (postfork)) |
2043 | if (forkcnt) |
2064 | if (forkcnt) |
2044 | { |
2065 | { |
2045 | queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK); |
2066 | queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK); |
2046 | call_pending (EV_A); |
2067 | invoke_cb (EV_A); |
2047 | } |
2068 | } |
2048 | #endif |
2069 | #endif |
2049 | |
2070 | |
2050 | /* queue prepare watchers (and execute them) */ |
2071 | /* queue prepare watchers (and execute them) */ |
2051 | if (expect_false (preparecnt)) |
2072 | if (expect_false (preparecnt)) |
2052 | { |
2073 | { |
2053 | queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE); |
2074 | queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE); |
2054 | call_pending (EV_A); |
2075 | invoke_cb (EV_A); |
2055 | } |
2076 | } |
2056 | |
2077 | |
2057 | /* we might have forked, so reify kernel state if necessary */ |
2078 | /* we might have forked, so reify kernel state if necessary */ |
2058 | if (expect_false (postfork)) |
2079 | if (expect_false (postfork)) |
2059 | loop_fork (EV_A); |
2080 | loop_fork (EV_A); |
… | |
… | |
2066 | ev_tstamp waittime = 0.; |
2087 | ev_tstamp waittime = 0.; |
2067 | ev_tstamp sleeptime = 0.; |
2088 | ev_tstamp sleeptime = 0.; |
2068 | |
2089 | |
2069 | if (expect_true (!(flags & EVLOOP_NONBLOCK || idleall || !activecnt))) |
2090 | if (expect_true (!(flags & EVLOOP_NONBLOCK || idleall || !activecnt))) |
2070 | { |
2091 | { |
|
|
2092 | /* remember old timestamp for io_blocktime calculation */ |
|
|
2093 | ev_tstamp prev_mn_now = mn_now; |
|
|
2094 | |
2071 | /* update time to cancel out callback processing overhead */ |
2095 | /* update time to cancel out callback processing overhead */ |
2072 | time_update (EV_A_ 1e100); |
2096 | time_update (EV_A_ 1e100); |
2073 | |
2097 | |
2074 | waittime = MAX_BLOCKTIME; |
2098 | waittime = MAX_BLOCKTIME; |
2075 | |
2099 | |
… | |
… | |
2085 | ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now + backend_fudge; |
2109 | ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now + backend_fudge; |
2086 | if (waittime > to) waittime = to; |
2110 | if (waittime > to) waittime = to; |
2087 | } |
2111 | } |
2088 | #endif |
2112 | #endif |
2089 | |
2113 | |
|
|
2114 | /* don't let timeouts decrease the waittime below timeout_blocktime */ |
2090 | if (expect_false (waittime < timeout_blocktime)) |
2115 | if (expect_false (waittime < timeout_blocktime)) |
2091 | waittime = timeout_blocktime; |
2116 | waittime = timeout_blocktime; |
2092 | |
2117 | |
2093 | sleeptime = waittime - backend_fudge; |
2118 | /* extra check because io_blocktime is commonly 0 */ |
2094 | |
|
|
2095 | if (expect_true (sleeptime > io_blocktime)) |
2119 | if (expect_false (io_blocktime)) |
2096 | sleeptime = io_blocktime; |
|
|
2097 | |
|
|
2098 | if (sleeptime) |
|
|
2099 | { |
2120 | { |
|
|
2121 | sleeptime = io_blocktime - (mn_now - prev_mn_now); |
|
|
2122 | |
|
|
2123 | if (sleeptime > waittime - backend_fudge) |
|
|
2124 | sleeptime = waittime - backend_fudge; |
|
|
2125 | |
|
|
2126 | if (expect_true (sleeptime > 0.)) |
|
|
2127 | { |
2100 | ev_sleep (sleeptime); |
2128 | ev_sleep (sleeptime); |
2101 | waittime -= sleeptime; |
2129 | waittime -= sleeptime; |
|
|
2130 | } |
2102 | } |
2131 | } |
2103 | } |
2132 | } |
2104 | |
2133 | |
2105 | ++loop_count; |
2134 | ++loop_count; |
2106 | backend_poll (EV_A_ waittime); |
2135 | backend_poll (EV_A_ waittime); |
… | |
… | |
2122 | |
2151 | |
2123 | /* queue check watchers, to be executed first */ |
2152 | /* queue check watchers, to be executed first */ |
2124 | if (expect_false (checkcnt)) |
2153 | if (expect_false (checkcnt)) |
2125 | queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); |
2154 | queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); |
2126 | |
2155 | |
2127 | call_pending (EV_A); |
2156 | invoke_cb (EV_A); |
2128 | } |
2157 | } |
2129 | while (expect_true ( |
2158 | while (expect_true ( |
2130 | activecnt |
2159 | activecnt |
2131 | && !loop_done |
2160 | && !loop_done |
2132 | && !(flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK)) |
2161 | && !(flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK)) |
2133 | )); |
2162 | )); |
2134 | |
2163 | |
2135 | if (loop_done == EVUNLOOP_ONE) |
2164 | if (loop_done == EVUNLOOP_ONE) |
2136 | loop_done = EVUNLOOP_CANCEL; |
2165 | loop_done = EVUNLOOP_CANCEL; |
|
|
2166 | |
|
|
2167 | --loop_depth; |
2137 | } |
2168 | } |
2138 | |
2169 | |
2139 | void |
2170 | void |
2140 | ev_unloop (EV_P_ int how) |
2171 | ev_unloop (EV_P_ int how) |
2141 | { |
2172 | { |
… | |
… | |
2233 | } |
2264 | } |
2234 | |
2265 | |
2235 | inline_size void |
2266 | inline_size void |
2236 | pri_adjust (EV_P_ W w) |
2267 | pri_adjust (EV_P_ W w) |
2237 | { |
2268 | { |
2238 | int pri = w->priority; |
2269 | int pri = ev_priority (w); |
2239 | pri = pri < EV_MINPRI ? EV_MINPRI : pri; |
2270 | pri = pri < EV_MINPRI ? EV_MINPRI : pri; |
2240 | pri = pri > EV_MAXPRI ? EV_MAXPRI : pri; |
2271 | pri = pri > EV_MAXPRI ? EV_MAXPRI : pri; |
2241 | w->priority = pri; |
2272 | ev_set_priority (w, pri); |
2242 | } |
2273 | } |
2243 | |
2274 | |
2244 | inline_speed void |
2275 | inline_speed void |
2245 | ev_start (EV_P_ W w, int active) |
2276 | ev_start (EV_P_ W w, int active) |
2246 | { |
2277 | { |