[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