summaryrefslogtreecommitdiff
path: root/ev.c
diff options
context:
space:
mode:
Diffstat (limited to 'ev.c')
-rw-r--r--ev.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/ev.c b/ev.c
index b70e452..3147d40 100644
--- a/ev.c
+++ b/ev.c
@@ -237,6 +237,14 @@ extern "C" {
# endif
#endif
+#ifndef EV_USE_4HEAP
+# define EV_USE_4HEAP !EV_MINIMAL
+#endif
+
+#ifndef EV_HEAP_CACHE_AT
+# define EV_HEAP_CACHE_AT !EV_MINIMAL
+#endif
+
/* this block fixes any misconfiguration where we know we run into trouble otherwise */
#ifndef CLOCK_MONOTONIC
@@ -432,11 +440,10 @@ typedef struct
#endif
/* Heap Entry */
-#define EV_HEAP_CACHE_AT 0
#if EV_HEAP_CACHE_AT
typedef struct {
- WT w;
ev_tstamp at;
+ WT w;
} ANHE;
#define ANHE_w(he) (he).w /* access watcher, read-write */
@@ -793,7 +800,6 @@ fd_rearm_all (EV_P)
* which is more cache-efficient.
* the difference is about 5% with 50000+ watchers.
*/
-#define EV_USE_4HEAP !EV_MINIMAL
#if EV_USE_4HEAP
#define DHEAP 4
@@ -888,7 +894,7 @@ upheap (ANHE *heap, int k)
k = p;
}
- heap [k] = w;
+ heap [k] = he;
ev_active (ANHE_w (heap [k])) = k;
}
@@ -908,7 +914,7 @@ downheap (ANHE *heap, int N, int k)
c += c + 1 < N && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
? 1 : 0;
- if (w->at <= ANHE_at (heap [c]))
+ if (ANHE_at (he) <= ANHE_at (heap [c]))
break;
heap [k] = heap [c];
@@ -1606,12 +1612,12 @@ timers_reify (EV_P)
/* first reschedule or stop timer */
if (w->repeat)
{
- assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
-
ev_at (w) += w->repeat;
if (ev_at (w) < mn_now)
ev_at (w) = mn_now;
+ assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
+
ANHE_at_set (timers [HEAP0]);
downheap (timers, timercnt, HEAP0);
}
@@ -1636,7 +1642,9 @@ periodics_reify (EV_P)
if (w->reschedule_cb)
{
ev_at (w) = w->reschedule_cb (w, ev_rt_now + TIME_EPSILON);
+
assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) > ev_rt_now));
+
ANHE_at_set (periodics [HEAP0]);
downheap (periodics, periodiccnt, HEAP0);
}
@@ -1644,7 +1652,9 @@ periodics_reify (EV_P)
{
ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
if (ev_at (w) - ev_rt_now <= TIME_EPSILON) ev_at (w) += w->interval;
+
assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ev_at (w) > ev_rt_now));
+
ANHE_at_set (periodics [HEAP0]);
downheap (periodics, periodiccnt, HEAP0);
}
@@ -1673,9 +1683,10 @@ periodics_reschedule (EV_P)
ANHE_at_set (periodics [i]);
}
- /* now rebuild the heap, this for the 2-heap, inefficient for the 4-heap, but correct */
- for (i = periodiccnt >> 1; --i; )
- downheap (periodics, periodiccnt, i + HEAP0);
+ /* we don't use floyds algorithm, uphead is simpler and is more cache-efficient */
+ /* also, this is easy and corretc for both 2-heaps and 4-heaps */
+ for (i = 0; i < periodiccnt; ++i)
+ upheap (periodics, i + HEAP0);
}
#endif
@@ -2088,6 +2099,7 @@ ev_periodic_start (EV_P_ ev_periodic *w)
ev_start (EV_A_ (W)w, ++periodiccnt + HEAP0 - 1);
array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
ANHE_w (periodics [ev_active (w)]) = (WT)w;
+ ANHE_at_set (periodics [ev_active (w)]);
upheap (periodics, ev_active (w));
/*assert (("internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/