… | |
… | |
536 | /*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */ |
536 | /*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */ |
537 | |
537 | |
538 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
538 | #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
539 | #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ |
539 | #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ |
540 | |
540 | |
541 | /* find a portable timestamp that is "alawys" in the future but fits into time_t. |
541 | /* find a portable timestamp that is "always" in the future but fits into time_t. |
542 | * this is quite hard, and we are mostly guessing - we handle 32 bit signed/unsigned time_t, |
542 | * this is quite hard, and we are mostly guessing - we handle 32 bit signed/unsigned time_t, |
543 | * and sizes large than 32 bit, but and maybe the unlikely loating point time_t */ |
543 | * and sizes larger than 32 bit, and maybe the unlikely floating point time_t */ |
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 | #define EV_TS_TO_MS(a) a * 1e3 + 0.9999 |
|
|
550 | #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) |
551 | #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) |
552 | #define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0) |
|
|
553 | #define EV_TV_GET(tv) ((tv).tv_sec + (tv).tv_usec * 1e-6) |
|
|
554 | #define EV_TS_GET(ts) ((ts).tv_sec + (ts).tv_nsec * 1e-9) |
551 | |
555 | |
552 | /* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ |
556 | /* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ |
553 | /* ECB.H BEGIN */ |
557 | /* ECB.H BEGIN */ |
554 | /* |
558 | /* |
555 | * libecb - http://software.schmorp.de/pkg/libecb |
559 | * libecb - http://software.schmorp.de/pkg/libecb |
… | |
… | |
1726 | const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.; |
1730 | const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.; |
1727 | #else |
1731 | #else |
1728 | const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.; |
1732 | const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.; |
1729 | #endif |
1733 | #endif |
1730 | |
1734 | |
|
|
1735 | /* special treatment for negative arguments */ |
|
|
1736 | if (ecb_expect_false (v < 0.)) |
|
|
1737 | { |
|
|
1738 | ev_tstamp f = -ev_floor (-v); |
|
|
1739 | |
|
|
1740 | return f - (f == v ? 0 : 1); |
|
|
1741 | } |
|
|
1742 | |
1731 | /* argument too large for an unsigned long? */ |
1743 | /* argument too large for an unsigned long? then reduce it */ |
1732 | if (ecb_expect_false (v >= shift)) |
1744 | if (ecb_expect_false (v >= shift)) |
1733 | { |
1745 | { |
1734 | ev_tstamp f; |
1746 | ev_tstamp f; |
1735 | |
1747 | |
1736 | if (v == v - 1.) |
1748 | if (v == v - 1.) |
1737 | return v; /* very large number */ |
1749 | return v; /* very large numbers are assumed to be integer */ |
1738 | |
1750 | |
1739 | f = shift * ev_floor (v * (1. / shift)); |
1751 | f = shift * ev_floor (v * (1. / shift)); |
1740 | return f + ev_floor (v - f); |
1752 | return f + ev_floor (v - f); |
1741 | } |
|
|
1742 | |
|
|
1743 | /* special treatment for negative args? */ |
|
|
1744 | if (ecb_expect_false (v < 0.)) |
|
|
1745 | { |
|
|
1746 | ev_tstamp f = -ev_floor (-v); |
|
|
1747 | |
|
|
1748 | return f - (f == v ? 0 : 1); |
|
|
1749 | } |
1753 | } |
1750 | |
1754 | |
1751 | /* fits into an unsigned long */ |
1755 | /* fits into an unsigned long */ |
1752 | return (unsigned long)v; |
1756 | return (unsigned long)v; |
1753 | } |
1757 | } |
… | |
… | |
1993 | #if EV_USE_REALTIME |
1997 | #if EV_USE_REALTIME |
1994 | if (ecb_expect_true (have_realtime)) |
1998 | if (ecb_expect_true (have_realtime)) |
1995 | { |
1999 | { |
1996 | struct timespec ts; |
2000 | struct timespec ts; |
1997 | clock_gettime (CLOCK_REALTIME, &ts); |
2001 | clock_gettime (CLOCK_REALTIME, &ts); |
1998 | return ts.tv_sec + ts.tv_nsec * 1e-9; |
2002 | return EV_TS_GET (ts); |
1999 | } |
2003 | } |
2000 | #endif |
2004 | #endif |
2001 | |
2005 | |
2002 | struct timeval tv; |
2006 | struct timeval tv; |
2003 | gettimeofday (&tv, 0); |
2007 | gettimeofday (&tv, 0); |
2004 | return tv.tv_sec + tv.tv_usec * 1e-6; |
2008 | return EV_TV_GET (tv); |
2005 | } |
2009 | } |
2006 | #endif |
2010 | #endif |
2007 | |
2011 | |
2008 | inline_size ev_tstamp |
2012 | inline_size ev_tstamp |
2009 | get_clock (void) |
2013 | get_clock (void) |
… | |
… | |
2011 | #if EV_USE_MONOTONIC |
2015 | #if EV_USE_MONOTONIC |
2012 | if (ecb_expect_true (have_monotonic)) |
2016 | if (ecb_expect_true (have_monotonic)) |
2013 | { |
2017 | { |
2014 | struct timespec ts; |
2018 | struct timespec ts; |
2015 | clock_gettime (CLOCK_MONOTONIC, &ts); |
2019 | clock_gettime (CLOCK_MONOTONIC, &ts); |
2016 | return ts.tv_sec + ts.tv_nsec * 1e-9; |
2020 | return EV_TS_GET (ts); |
2017 | } |
2021 | } |
2018 | #endif |
2022 | #endif |
2019 | |
2023 | |
2020 | return ev_time (); |
2024 | return ev_time (); |
2021 | } |
2025 | } |
… | |
… | |
2039 | EV_TS_SET (ts, delay); |
2043 | EV_TS_SET (ts, delay); |
2040 | nanosleep (&ts, 0); |
2044 | nanosleep (&ts, 0); |
2041 | #elif defined _WIN32 |
2045 | #elif defined _WIN32 |
2042 | /* maybe this should round up, as ms is very low resolution */ |
2046 | /* maybe this should round up, as ms is very low resolution */ |
2043 | /* compared to select (µs) or nanosleep (ns) */ |
2047 | /* compared to select (µs) or nanosleep (ns) */ |
2044 | Sleep ((unsigned long)(delay * 1e3)); |
2048 | Sleep ((unsigned long)(EV_TS_TO_MS (delay))); |
2045 | #else |
2049 | #else |
2046 | struct timeval tv; |
2050 | struct timeval tv; |
2047 | |
2051 | |
2048 | /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ |
2052 | /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ |
2049 | /* something not guaranteed by newer posix versions, but guaranteed */ |
2053 | /* something not guaranteed by newer posix versions, but guaranteed */ |
… | |
… | |
2399 | |
2403 | |
2400 | /* find minimum child */ |
2404 | /* find minimum child */ |
2401 | if (ecb_expect_true (pos + DHEAP - 1 < E)) |
2405 | if (ecb_expect_true (pos + DHEAP - 1 < E)) |
2402 | { |
2406 | { |
2403 | /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2407 | /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2404 | if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2408 | if ( minat > ANHE_at (pos [1])) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2405 | if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2409 | if ( minat > ANHE_at (pos [2])) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2406 | if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2410 | if ( minat > ANHE_at (pos [3])) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2407 | } |
2411 | } |
2408 | else if (pos < E) |
2412 | else if (pos < E) |
2409 | { |
2413 | { |
2410 | /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2414 | /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); |
2411 | if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2415 | if (pos + 1 < E && minat > ANHE_at (pos [1])) (minpos = pos + 1), (minat = ANHE_at (*minpos)); |
2412 | if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2416 | if (pos + 2 < E && minat > ANHE_at (pos [2])) (minpos = pos + 2), (minat = ANHE_at (*minpos)); |
2413 | if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2417 | if (pos + 3 < E && minat > ANHE_at (pos [3])) (minpos = pos + 3), (minat = ANHE_at (*minpos)); |
2414 | } |
2418 | } |
2415 | else |
2419 | else |
2416 | break; |
2420 | break; |
2417 | |
2421 | |
2418 | if (ANHE_at (he) <= minat) |
2422 | if (ANHE_at (he) <= minat) |
… | |
… | |
2426 | |
2430 | |
2427 | heap [k] = he; |
2431 | heap [k] = he; |
2428 | ev_active (ANHE_w (he)) = k; |
2432 | ev_active (ANHE_w (he)) = k; |
2429 | } |
2433 | } |
2430 | |
2434 | |
2431 | #else /* 4HEAP */ |
2435 | #else /* not 4HEAP */ |
2432 | |
2436 | |
2433 | #define HEAP0 1 |
2437 | #define HEAP0 1 |
2434 | #define HPARENT(k) ((k) >> 1) |
2438 | #define HPARENT(k) ((k) >> 1) |
2435 | #define UPHEAP_DONE(p,k) (!(p)) |
2439 | #define UPHEAP_DONE(p,k) (!(p)) |
2436 | |
2440 | |