… | |
… | |
544 | #define EV_TSTAMP_HUGE \ |
544 | #define EV_TSTAMP_HUGE \ |
545 | (sizeof (time_t) >= 8 ? 10000000000000. \ |
545 | (sizeof (time_t) >= 8 ? 10000000000000. \ |
546 | : 0 < (time_t)4294967295 ? 4294967295. \ |
546 | : 0 < (time_t)4294967295 ? 4294967295. \ |
547 | : 2147483647.) \ |
547 | : 2147483647.) \ |
548 | |
548 | |
|
|
549 | #ifndef EV_TS_CONST |
|
|
550 | # define EV_TS_CONST(nv) nv |
|
|
551 | # define EV_TS_TO_MSEC(a) a * 1e3 + 0.9999 |
|
|
552 | # define EV_TS_FROM_USEC(us) us * 1e-6 |
549 | #define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0) |
553 | # define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0) |
550 | #define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0) |
554 | # define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0) |
551 | #define EV_TV_GET(tv) ((tv).tv_sec + (tv).tv_usec * 1e6) |
555 | # define EV_TV_GET(tv) ((tv).tv_sec + (tv).tv_usec * 1e-6) |
552 | #define EV_TS_GET(ts) ((ts).tv_sec + (ts).tv_nsec * 1e9) |
556 | # define EV_TS_GET(ts) ((ts).tv_sec + (ts).tv_nsec * 1e-9) |
|
|
557 | #endif |
553 | |
558 | |
554 | /* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ |
559 | /* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ |
555 | /* ECB.H BEGIN */ |
560 | /* ECB.H BEGIN */ |
556 | /* |
561 | /* |
557 | * libecb - http://software.schmorp.de/pkg/libecb |
562 | * libecb - http://software.schmorp.de/pkg/libecb |
… | |
… | |
1963 | static struct ev_loop default_loop_struct; |
1968 | static struct ev_loop default_loop_struct; |
1964 | EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */ |
1969 | EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */ |
1965 | |
1970 | |
1966 | #else |
1971 | #else |
1967 | |
1972 | |
1968 | EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a definition despite extern */ |
1973 | EV_API_DECL ev_tstamp ev_rt_now = EV_TS_CONST (0.); /* needs to be initialised to make it a definition despite extern */ |
1969 | #define VAR(name,decl) static decl; |
1974 | #define VAR(name,decl) static decl; |
1970 | #include "ev_vars.h" |
1975 | #include "ev_vars.h" |
1971 | #undef VAR |
1976 | #undef VAR |
1972 | |
1977 | |
1973 | static int ev_default_loop_ptr; |
1978 | static int ev_default_loop_ptr; |
… | |
… | |
1999 | clock_gettime (CLOCK_REALTIME, &ts); |
2004 | clock_gettime (CLOCK_REALTIME, &ts); |
2000 | return EV_TS_GET (ts); |
2005 | return EV_TS_GET (ts); |
2001 | } |
2006 | } |
2002 | #endif |
2007 | #endif |
2003 | |
2008 | |
|
|
2009 | { |
2004 | struct timeval tv; |
2010 | struct timeval tv; |
2005 | gettimeofday (&tv, 0); |
2011 | gettimeofday (&tv, 0); |
2006 | return EV_TV_GET (tv); |
2012 | return EV_TV_GET (tv); |
|
|
2013 | } |
2007 | } |
2014 | } |
2008 | #endif |
2015 | #endif |
2009 | |
2016 | |
2010 | inline_size ev_tstamp |
2017 | inline_size ev_tstamp |
2011 | get_clock (void) |
2018 | get_clock (void) |
… | |
… | |
2031 | #endif |
2038 | #endif |
2032 | |
2039 | |
2033 | void |
2040 | void |
2034 | ev_sleep (ev_tstamp delay) EV_NOEXCEPT |
2041 | ev_sleep (ev_tstamp delay) EV_NOEXCEPT |
2035 | { |
2042 | { |
2036 | if (delay > 0.) |
2043 | if (delay > EV_TS_CONST (0.)) |
2037 | { |
2044 | { |
2038 | #if EV_USE_NANOSLEEP |
2045 | #if EV_USE_NANOSLEEP |
2039 | struct timespec ts; |
2046 | struct timespec ts; |
2040 | |
2047 | |
2041 | EV_TS_SET (ts, delay); |
2048 | EV_TS_SET (ts, delay); |
2042 | nanosleep (&ts, 0); |
2049 | nanosleep (&ts, 0); |
2043 | #elif defined _WIN32 |
2050 | #elif defined _WIN32 |
2044 | /* maybe this should round up, as ms is very low resolution */ |
2051 | /* maybe this should round up, as ms is very low resolution */ |
2045 | /* compared to select (µs) or nanosleep (ns) */ |
2052 | /* compared to select (µs) or nanosleep (ns) */ |
2046 | Sleep ((unsigned long)(delay * 1e3)); |
2053 | Sleep ((unsigned long)(EV_TS_TO_MSEC (delay))); |
2047 | #else |
2054 | #else |
2048 | struct timeval tv; |
2055 | struct timeval tv; |
2049 | |
2056 | |
2050 | /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ |
2057 | /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ |
2051 | /* something not guaranteed by newer posix versions, but guaranteed */ |
2058 | /* something not guaranteed by newer posix versions, but guaranteed */ |
… | |
… | |
2401 | |
2408 | |
2402 | /* find minimum child */ |
2409 | /* find minimum child */ |
2403 | if (ecb_expect_true (pos + DHEAP - 1 < E)) |
2410 | if (ecb_expect_true (pos + DHEAP - 1 < E)) |
2404 | { |
2411 | { |
2405 | /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2412 | /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2406 | if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2413 | if ( minat > ANHE_at (pos [1])) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2407 | if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2414 | if ( minat > ANHE_at (pos [2])) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2408 | if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2415 | if ( minat > ANHE_at (pos [3])) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2409 | } |
2416 | } |
2410 | else if (pos < E) |
2417 | else if (pos < E) |
2411 | { |
2418 | { |
2412 | /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2419 | /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2413 | if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2420 | if (pos + 1 < E && minat > ANHE_at (pos [1])) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2414 | if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2421 | if (pos + 2 < E && minat > ANHE_at (pos [2])) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2415 | if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2422 | if (pos + 3 < E && minat > ANHE_at (pos [3])) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2416 | } |
2423 | } |
2417 | else |
2424 | else |
2418 | break; |
2425 | break; |
2419 | |
2426 | |
2420 | if (ANHE_at (he) <= minat) |
2427 | if (ANHE_at (he) <= minat) |
… | |
… | |
2428 | |
2435 | |
2429 | heap [k] = he; |
2436 | heap [k] = he; |
2430 | ev_active (ANHE_w (he)) = k; |
2437 | ev_active (ANHE_w (he)) = k; |
2431 | } |
2438 | } |
2432 | |
2439 | |
2433 | #else /* 4HEAP */ |
2440 | #else /* not 4HEAP */ |
2434 | |
2441 | |
2435 | #define HEAP0 1 |
2442 | #define HEAP0 1 |
2436 | #define HPARENT(k) ((k) >> 1) |
2443 | #define HPARENT(k) ((k) >> 1) |
2437 | #define UPHEAP_DONE(p,k) (!(p)) |
2444 | #define UPHEAP_DONE(p,k) (!(p)) |
2438 | |
2445 | |
… | |
… | |
3542 | { |
3549 | { |
3543 | ev_at (w) += w->repeat; |
3550 | ev_at (w) += w->repeat; |
3544 | if (ev_at (w) < mn_now) |
3551 | if (ev_at (w) < mn_now) |
3545 | ev_at (w) = mn_now; |
3552 | ev_at (w) = mn_now; |
3546 | |
3553 | |
3547 | assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.)); |
3554 | assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > EV_TS_CONST (0.))); |
3548 | |
3555 | |
3549 | ANHE_at_cache (timers [HEAP0]); |
3556 | ANHE_at_cache (timers [HEAP0]); |
3550 | downheap (timers, timercnt, HEAP0); |
3557 | downheap (timers, timercnt, HEAP0); |
3551 | } |
3558 | } |
3552 | else |
3559 | else |
… | |
… | |
3683 | |
3690 | |
3684 | mn_now = get_clock (); |
3691 | mn_now = get_clock (); |
3685 | |
3692 | |
3686 | /* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */ |
3693 | /* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */ |
3687 | /* interpolate in the meantime */ |
3694 | /* interpolate in the meantime */ |
3688 | if (ecb_expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5)) |
3695 | if (ecb_expect_true (mn_now - now_floor < EV_TS_CONST (MIN_TIMEJUMP * .5))) |
3689 | { |
3696 | { |
3690 | ev_rt_now = rtmn_diff + mn_now; |
3697 | ev_rt_now = rtmn_diff + mn_now; |
3691 | return; |
3698 | return; |
3692 | } |
3699 | } |
3693 | |
3700 | |
… | |
… | |
3707 | ev_tstamp diff; |
3714 | ev_tstamp diff; |
3708 | rtmn_diff = ev_rt_now - mn_now; |
3715 | rtmn_diff = ev_rt_now - mn_now; |
3709 | |
3716 | |
3710 | diff = odiff - rtmn_diff; |
3717 | diff = odiff - rtmn_diff; |
3711 | |
3718 | |
3712 | if (ecb_expect_true ((diff < 0. ? -diff : diff) < MIN_TIMEJUMP)) |
3719 | if (ecb_expect_true ((diff < EV_TS_CONST (0.) ? -diff : diff) < EV_TS_CONST (MIN_TIMEJUMP))) |
3713 | return; /* all is well */ |
3720 | return; /* all is well */ |
3714 | |
3721 | |
3715 | ev_rt_now = ev_time (); |
3722 | ev_rt_now = ev_time (); |
3716 | mn_now = get_clock (); |
3723 | mn_now = get_clock (); |
3717 | now_floor = mn_now; |
3724 | now_floor = mn_now; |
… | |
… | |
3726 | else |
3733 | else |
3727 | #endif |
3734 | #endif |
3728 | { |
3735 | { |
3729 | ev_rt_now = ev_time (); |
3736 | ev_rt_now = ev_time (); |
3730 | |
3737 | |
3731 | if (ecb_expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + MIN_TIMEJUMP)) |
3738 | if (ecb_expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + EV_TS_CONST (MIN_TIMEJUMP))) |
3732 | { |
3739 | { |
3733 | /* adjust timers. this is easy, as the offset is the same for all of them */ |
3740 | /* adjust timers. this is easy, as the offset is the same for all of them */ |
3734 | timers_reschedule (EV_A_ ev_rt_now - mn_now); |
3741 | timers_reschedule (EV_A_ ev_rt_now - mn_now); |
3735 | #if EV_PERIODIC_ENABLE |
3742 | #if EV_PERIODIC_ENABLE |
3736 | periodics_reschedule (EV_A); |
3743 | periodics_reschedule (EV_A); |
… | |
… | |
3805 | |
3812 | |
3806 | /* remember old timestamp for io_blocktime calculation */ |
3813 | /* remember old timestamp for io_blocktime calculation */ |
3807 | ev_tstamp prev_mn_now = mn_now; |
3814 | ev_tstamp prev_mn_now = mn_now; |
3808 | |
3815 | |
3809 | /* update time to cancel out callback processing overhead */ |
3816 | /* update time to cancel out callback processing overhead */ |
3810 | time_update (EV_A_ 1e100); |
3817 | time_update (EV_A_ EV_TS_CONST (EV_TSTAMP_HUGE)); |
3811 | |
3818 | |
3812 | /* from now on, we want a pipe-wake-up */ |
3819 | /* from now on, we want a pipe-wake-up */ |
3813 | pipe_write_wanted = 1; |
3820 | pipe_write_wanted = 1; |
3814 | |
3821 | |
3815 | ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */ |
3822 | ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */ |
3816 | |
3823 | |
3817 | if (ecb_expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) |
3824 | if (ecb_expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) |
3818 | { |
3825 | { |
3819 | waittime = MAX_BLOCKTIME; |
3826 | waittime = EV_TS_CONST (MAX_BLOCKTIME); |
3820 | |
3827 | |
3821 | if (timercnt) |
3828 | if (timercnt) |
3822 | { |
3829 | { |
3823 | ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; |
3830 | ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; |
3824 | if (waittime > to) waittime = to; |
3831 | if (waittime > to) waittime = to; |
… | |
… | |
3847 | sleeptime = io_blocktime - (mn_now - prev_mn_now); |
3854 | sleeptime = io_blocktime - (mn_now - prev_mn_now); |
3848 | |
3855 | |
3849 | if (sleeptime > waittime - backend_mintime) |
3856 | if (sleeptime > waittime - backend_mintime) |
3850 | sleeptime = waittime - backend_mintime; |
3857 | sleeptime = waittime - backend_mintime; |
3851 | |
3858 | |
3852 | if (ecb_expect_true (sleeptime > 0.)) |
3859 | if (ecb_expect_true (sleeptime > EV_TS_CONST (0.))) |
3853 | { |
3860 | { |
3854 | ev_sleep (sleeptime); |
3861 | ev_sleep (sleeptime); |
3855 | waittime -= sleeptime; |
3862 | waittime -= sleeptime; |
3856 | } |
3863 | } |
3857 | } |
3864 | } |
… | |
… | |
3931 | } |
3938 | } |
3932 | |
3939 | |
3933 | void |
3940 | void |
3934 | ev_now_update (EV_P) EV_NOEXCEPT |
3941 | ev_now_update (EV_P) EV_NOEXCEPT |
3935 | { |
3942 | { |
3936 | time_update (EV_A_ 1e100); |
3943 | time_update (EV_A_ EV_TSTAMP_HUGE); |
3937 | } |
3944 | } |
3938 | |
3945 | |
3939 | void |
3946 | void |
3940 | ev_suspend (EV_P) EV_NOEXCEPT |
3947 | ev_suspend (EV_P) EV_NOEXCEPT |
3941 | { |
3948 | { |
… | |
… | |
4172 | } |
4179 | } |
4173 | |
4180 | |
4174 | ev_tstamp |
4181 | ev_tstamp |
4175 | ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT |
4182 | ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT |
4176 | { |
4183 | { |
4177 | return ev_at (w) - (ev_is_active (w) ? mn_now : 0.); |
4184 | return ev_at (w) - (ev_is_active (w) ? mn_now : EV_TS_CONST (0.)); |
4178 | } |
4185 | } |
4179 | |
4186 | |
4180 | #if EV_PERIODIC_ENABLE |
4187 | #if EV_PERIODIC_ENABLE |
4181 | ecb_noinline |
4188 | ecb_noinline |
4182 | void |
4189 | void |