ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.c
(Generate patch)

Comparing libev/ev.c (file contents):
Revision 1.241 by root, Fri May 9 13:57:00 2008 UTC vs.
Revision 1.244 by root, Tue May 20 23:49:41 2008 UTC

235# else 235# else
236# define EV_USE_EVENTFD 0 236# define EV_USE_EVENTFD 0
237# endif 237# endif
238#endif 238#endif
239 239
240#ifndef EV_USE_4HEAP
241# define EV_USE_4HEAP !EV_MINIMAL
242#endif
243
244#ifndef EV_HEAP_CACHE_AT
245# define EV_HEAP_CACHE_AT !EV_MINIMAL
246#endif
247
240/* this block fixes any misconfiguration where we know we run into trouble otherwise */ 248/* this block fixes any misconfiguration where we know we run into trouble otherwise */
241 249
242#ifndef CLOCK_MONOTONIC 250#ifndef CLOCK_MONOTONIC
243# undef EV_USE_MONOTONIC 251# undef EV_USE_MONOTONIC
244# define EV_USE_MONOTONIC 0 252# define EV_USE_MONOTONIC 0
432#endif 440#endif
433 441
434/* Heap Entry */ 442/* Heap Entry */
435#if EV_HEAP_CACHE_AT 443#if EV_HEAP_CACHE_AT
436 typedef struct { 444 typedef struct {
445 ev_tstamp at;
437 WT w; 446 WT w;
438 ev_tstamp at;
439 } ANHE; 447 } ANHE;
440 448
441 #define ANHE_w(he) (he) /* access watcher, read-write */ 449 #define ANHE_w(he) (he).w /* access watcher, read-write */
442 #define ANHE_at(he) (he)->at /* acces cahced at, read-only */ 450 #define ANHE_at(he) (he).at /* access cached at, read-only */
443 #define ANHE_at_set(he) (he)->at = (he)->w->at /* update at from watcher */ 451 #define ANHE_at_set(he) (he).at = (he).w->at /* update at from watcher */
444#else 452#else
445 typedef WT ANHE; 453 typedef WT ANHE;
446 454
447 #define ANHE_w(he) (he) 455 #define ANHE_w(he) (he)
448 #define ANHE_at(he) (he)->at 456 #define ANHE_at(he) (he)->at
790 * at the moment we allow libev the luxury of two heaps, 798 * at the moment we allow libev the luxury of two heaps,
791 * a small-code-size 2-heap one and a ~1.5kb larger 4-heap 799 * a small-code-size 2-heap one and a ~1.5kb larger 4-heap
792 * which is more cache-efficient. 800 * which is more cache-efficient.
793 * the difference is about 5% with 50000+ watchers. 801 * the difference is about 5% with 50000+ watchers.
794 */ 802 */
795#define EV_USE_4HEAP !EV_MINIMAL
796#if EV_USE_4HEAP 803#if EV_USE_4HEAP
797 804
798#define DHEAP 4 805#define DHEAP 4
799#define HEAP0 (DHEAP - 1) /* index of first element in heap */ 806#define HEAP0 (DHEAP - 1) /* index of first element in heap */
800 807
885 heap [k] = heap [p]; 892 heap [k] = heap [p];
886 ev_active (ANHE_w (heap [k])) = k; 893 ev_active (ANHE_w (heap [k])) = k;
887 k = p; 894 k = p;
888 } 895 }
889 896
890 heap [k] = w; 897 heap [k] = he;
891 ev_active (ANHE_w (heap [k])) = k; 898 ev_active (ANHE_w (heap [k])) = k;
892} 899}
893 900
894/* away from the root */ 901/* away from the root */
895void inline_speed 902void inline_speed
905 break; 912 break;
906 913
907 c += c + 1 < N && ANHE_at (heap [c]) > ANHE_at (heap [c + 1]) 914 c += c + 1 < N && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
908 ? 1 : 0; 915 ? 1 : 0;
909 916
910 if (w->at <= ANHE_at (heap [c])) 917 if (ANHE_at (he) <= ANHE_at (heap [c]))
911 break; 918 break;
912 919
913 heap [k] = heap [c]; 920 heap [k] = heap [c];
914 ev_active (ANHE_w (heap [k])) = k; 921 ev_active (ANHE_w (heap [k])) = k;
915 922
1594#endif 1601#endif
1595 1602
1596void inline_size 1603void inline_size
1597timers_reify (EV_P) 1604timers_reify (EV_P)
1598{ 1605{
1599 while (timercnt && ANHE_at (timers [HEAP0]) <= mn_now) 1606 while (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
1600 { 1607 {
1601 ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]); 1608 ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
1602 1609
1603 /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/ 1610 /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/
1604 1611
1605 /* first reschedule or stop timer */ 1612 /* first reschedule or stop timer */
1606 if (w->repeat) 1613 if (w->repeat)
1607 { 1614 {
1608 assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
1609
1610 ev_at (w) += w->repeat; 1615 ev_at (w) += w->repeat;
1611 if (ev_at (w) < mn_now) 1616 if (ev_at (w) < mn_now)
1612 ev_at (w) = mn_now; 1617 ev_at (w) = mn_now;
1613 1618
1619 assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
1620
1621 ANHE_at_set (timers [HEAP0]);
1614 downheap (timers, timercnt, HEAP0); 1622 downheap (timers, timercnt, HEAP0);
1615 } 1623 }
1616 else 1624 else
1617 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ 1625 ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
1618 1626
1622 1630
1623#if EV_PERIODIC_ENABLE 1631#if EV_PERIODIC_ENABLE
1624void inline_size 1632void inline_size
1625periodics_reify (EV_P) 1633periodics_reify (EV_P)
1626{ 1634{
1627 while (periodiccnt && ANHE_at (periodics [HEAP0]) <= ev_rt_now) 1635 while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
1628 { 1636 {
1629 ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]); 1637 ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
1630 1638
1631 /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/ 1639 /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/
1632 1640
1633 /* first reschedule or stop timer */ 1641 /* first reschedule or stop timer */
1634 if (w->reschedule_cb) 1642 if (w->reschedule_cb)
1635 { 1643 {
1636 ev_at (w) = w->reschedule_cb (w, ev_rt_now + TIME_EPSILON); 1644 ev_at (w) = w->reschedule_cb (w, ev_rt_now);
1645
1637 assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) > ev_rt_now)); 1646 assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
1647
1648 ANHE_at_set (periodics [HEAP0]);
1638 downheap (periodics, periodiccnt, 1); 1649 downheap (periodics, periodiccnt, HEAP0);
1639 } 1650 }
1640 else if (w->interval) 1651 else if (w->interval)
1641 { 1652 {
1642 ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval; 1653 ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
1643 if (ev_at (w) - ev_rt_now <= TIME_EPSILON) ev_at (w) += w->interval; 1654 if (ev_at (w) - ev_rt_now <= TIME_EPSILON) ev_at (w) += w->interval;
1655
1644 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ev_at (w) > ev_rt_now)); 1656 assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ev_at (w) >= ev_rt_now));
1657
1658 ANHE_at_set (periodics [HEAP0]);
1645 downheap (periodics, periodiccnt, HEAP0); 1659 downheap (periodics, periodiccnt, HEAP0);
1646 } 1660 }
1647 else 1661 else
1648 ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ 1662 ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
1649 1663
1663 1677
1664 if (w->reschedule_cb) 1678 if (w->reschedule_cb)
1665 ev_at (w) = w->reschedule_cb (w, ev_rt_now); 1679 ev_at (w) = w->reschedule_cb (w, ev_rt_now);
1666 else if (w->interval) 1680 else if (w->interval)
1667 ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval; 1681 ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
1668 }
1669 1682
1670 /* now rebuild the heap, this for the 2-heap, inefficient for the 4-heap, but correct */ 1683 ANHE_at_set (periodics [i]);
1671 for (i = periodiccnt >> 1; --i; ) 1684 }
1685
1686 /* we don't use floyds algorithm, uphead is simpler and is more cache-efficient */
1687 /* also, this is easy and corretc for both 2-heaps and 4-heaps */
1688 for (i = 0; i < periodiccnt; ++i)
1672 downheap (periodics, periodiccnt, i + HEAP0); 1689 upheap (periodics, i + HEAP0);
1673} 1690}
1674#endif 1691#endif
1675 1692
1676void inline_speed 1693void inline_speed
1677time_update (EV_P_ ev_tstamp max_block) 1694time_update (EV_P_ ev_tstamp max_block)
1985{ 2002{
1986 clear_pending (EV_A_ (W)w); 2003 clear_pending (EV_A_ (W)w);
1987 if (expect_false (!ev_is_active (w))) 2004 if (expect_false (!ev_is_active (w)))
1988 return; 2005 return;
1989 2006
1990 assert (("ev_io_start called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); 2007 assert (("ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
1991 2008
1992 wlist_del (&anfds[w->fd].head, (WL)w); 2009 wlist_del (&anfds[w->fd].head, (WL)w);
1993 ev_stop (EV_A_ (W)w); 2010 ev_stop (EV_A_ (W)w);
1994 2011
1995 fd_change (EV_A_ w->fd, 1); 2012 fd_change (EV_A_ w->fd, 1);
2009 array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2); 2026 array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
2010 ANHE_w (timers [ev_active (w)]) = (WT)w; 2027 ANHE_w (timers [ev_active (w)]) = (WT)w;
2011 ANHE_at_set (timers [ev_active (w)]); 2028 ANHE_at_set (timers [ev_active (w)]);
2012 upheap (timers, ev_active (w)); 2029 upheap (timers, ev_active (w));
2013 2030
2014 /*assert (("internal timer heap corruption", timers [ev_active (w)] == w));*/ 2031 /*assert (("internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
2015} 2032}
2016 2033
2017void noinline 2034void noinline
2018ev_timer_stop (EV_P_ ev_timer *w) 2035ev_timer_stop (EV_P_ ev_timer *w)
2019{ 2036{
2080 ev_at (w) = w->offset; 2097 ev_at (w) = w->offset;
2081 2098
2082 ev_start (EV_A_ (W)w, ++periodiccnt + HEAP0 - 1); 2099 ev_start (EV_A_ (W)w, ++periodiccnt + HEAP0 - 1);
2083 array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2); 2100 array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
2084 ANHE_w (periodics [ev_active (w)]) = (WT)w; 2101 ANHE_w (periodics [ev_active (w)]) = (WT)w;
2102 ANHE_at_set (periodics [ev_active (w)]);
2085 upheap (periodics, ev_active (w)); 2103 upheap (periodics, ev_active (w));
2086 2104
2087 /*assert (("internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/ 2105 /*assert (("internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
2088} 2106}
2089 2107

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines