[master] 754f386 Make the poll waiter also use the binheap
Poul-Henning Kamp
phk at FreeBSD.org
Wed May 27 23:38:32 CEST 2015
commit 754f386d663b66289cf75b664bad5671a50578dd
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed May 27 10:54:00 2015 +0000
Make the poll waiter also use the binheap
diff --git a/bin/varnishd/waiter/cache_waiter.c b/bin/varnishd/waiter/cache_waiter.c
index d3a33ca..4d2f794 100644
--- a/bin/varnishd/waiter/cache_waiter.c
+++ b/bin/varnishd/waiter/cache_waiter.c
@@ -51,7 +51,7 @@ waited_cmp(void *priv, const void *a, const void *b)
CAST_OBJ_NOTNULL(aa, a, WAITED_MAGIC);
CAST_OBJ_NOTNULL(bb, b, WAITED_MAGIC);
- return (aa->idle + Wait_Tmo(ww, aa) < bb->idle + Wait_Tmo(ww, bb));
+ return (Wait_When(ww, aa) < Wait_When(ww, bb));
}
static void __match_proto__(binheap_update_t)
@@ -99,11 +99,13 @@ Wait_HeapDue(const struct waiter *w, struct waited **wpp)
wp = binheap_root(w->heap);
CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
if (wp == NULL) {
- *wpp = NULL;
+ if (wpp != NULL)
+ *wpp = NULL;
return (0);
}
- *wpp = wp;
- return(wp->idle + Wait_Tmo(w, wp));
+ if (wpp != NULL)
+ *wpp = wp;
+ return(Wait_When(w, wp));
}
/**********************************************************************/
diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c
index f8af96e..ea5ea22 100644
--- a/bin/varnishd/waiter/cache_waiter_kqueue.c
+++ b/bin/varnishd/waiter/cache_waiter_kqueue.c
@@ -148,7 +148,7 @@ vwk_enter(void *priv, struct waited *wp)
AZ(kevent(vwk->kq, &ke, 1, NULL, 0, NULL));
/* If the kqueue isn't due before our timeout, poke it via the pipe */
- if (Wait_Tmo(vwk->waiter, wp) < vwk->next)
+ if (Wait_When(vwk->waiter, wp) < vwk->next)
assert(write(vwk->pipe[1], "X", 1) == 1);
Lck_Unlock(&vwk->mtx);
diff --git a/bin/varnishd/waiter/cache_waiter_poll.c b/bin/varnishd/waiter/cache_waiter_poll.c
index 2de4402..5c56f9b 100644
--- a/bin/varnishd/waiter/cache_waiter_poll.c
+++ b/bin/varnishd/waiter/cache_waiter_poll.c
@@ -92,20 +92,22 @@ vwp_extend_pollspace(struct vwp *vwp)
/*--------------------------------------------------------------------*/
static void
-vwp_add(struct vwp *vwp, struct waited *w)
+vwp_add(struct vwp *vwp, struct waited *wp)
{
- CHECK_OBJ_NOTNULL(w, WAITED_MAGIC);
+VSL(SLT_Debug, wp->fd, "ADD");
+ CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
CHECK_OBJ_NOTNULL(vwp, VWP_MAGIC);
if (vwp->hpoll == vwp->npoll)
vwp_extend_pollspace(vwp);
assert(vwp->hpoll < vwp->npoll);
assert(vwp->pollfd[vwp->hpoll].fd == -1);
AZ(vwp->idx[vwp->hpoll]);
- vwp->pollfd[vwp->hpoll].fd = w->fd;
+ vwp->pollfd[vwp->hpoll].fd = wp->fd;
vwp->pollfd[vwp->hpoll].events = POLLIN;
- vwp->idx[vwp->hpoll] = w;
+ vwp->idx[vwp->hpoll] = wp;
vwp->hpoll++;
+ Wait_HeapInsert(vwp->waiter, wp);
}
static void
@@ -116,6 +118,7 @@ vwp_del(struct vwp *vwp, int n)
vwp->pollfd[n] = vwp->pollfd[vwp->hpoll];
vwp->idx[n] = vwp->idx[vwp->hpoll];
}
+VSL(SLT_Debug, vwp->pollfd[vwp->hpoll].fd, "DEL");
memset(&vwp->pollfd[vwp->hpoll], 0, sizeof(*vwp->pollfd));
vwp->pollfd[vwp->hpoll].fd = -1;
vwp->idx[vwp->hpoll] = NULL;
@@ -154,34 +157,34 @@ vwp_main(void *priv)
int v;
struct vwp *vwp;
struct waited *wp;
- double now, idle;
- int i, dopipe;
+ double now, then;
+ int i;
THR_SetName("cache-poll");
CAST_OBJ_NOTNULL(vwp, priv, VWP_MAGIC);
while (1) {
- v = poll(vwp->pollfd, vwp->hpoll,
- (int)floor(1e3 * Wait_Tmo(vwp->waiter, NULL)));
+ then = Wait_HeapDue(vwp->waiter, &wp);
+ if (wp == NULL)
+ i = -1;
+ else
+ i = (int)floor(1e3 * (then - VTIM_real()));
+ v = poll(vwp->pollfd, vwp->hpoll, i);
assert(v >= 0);
- if (v == 0)
- v = vwp->hpoll;
now = VTIM_real();
- idle = now - Wait_Tmo(vwp->waiter, NULL);
- i = 0;
- dopipe = 0;
- while (v > 0 && i < vwp->hpoll) {
- if (vwp->pollfd[i].revents)
- v--;
- if (vwp->pollfd[i].fd == vwp->pipes[0]) {
- if (vwp->pollfd[i].revents)
- dopipe = 1;
- i++;
- continue;
- }
+ if (vwp->pollfd[0].revents)
+ v--;
+ for (i = 1; i < vwp->hpoll;) {
+ assert(vwp->pollfd[i].fd != vwp->pipes[0]);
wp = vwp->idx[i];
CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
- if (wp->idle <= idle) {
+
+ if (v == 0 && Wait_HeapDue(vwp->waiter, NULL) > now)
+ break;
+ if (vwp->pollfd[i].revents)
+ v--;
+ then = Wait_When(vwp->waiter, wp);
+ if (then <= now) {
Wait_Call(vwp->waiter, wp, WAITER_TIMEOUT, now);
vwp_del(vwp, i);
} else if (vwp->pollfd[i].revents & POLLIN) {
@@ -193,7 +196,7 @@ vwp_main(void *priv)
i++;
}
}
- if (dopipe)
+ if (vwp->pollfd[0].revents)
vwp_dopipe(vwp);
}
NEEDLESS_RETURN(NULL);
diff --git a/bin/varnishd/waiter/waiter_priv.h b/bin/varnishd/waiter/waiter_priv.h
index 5215995..331e3ad 100644
--- a/bin/varnishd/waiter/waiter_priv.h
+++ b/bin/varnishd/waiter/waiter_priv.h
@@ -70,6 +70,12 @@ Wait_Tmo(const struct waiter *w, const struct waited *wp)
return (*w->waitfor->tmo);
}
+static inline double
+Wait_When(const struct waiter *w, const struct waited *wp)
+{
+ return (Wait_Tmo(w, wp) + wp->idle);
+}
+
void Wait_Call(const struct waiter *, struct waited *,
enum wait_event ev, double now);
void Wait_HeapInsert(const struct waiter *, struct waited *);
More information about the varnish-commit
mailing list