[4.1] 3c1c970 Dramatically simplify VEV
PÃ¥l Hermunn Johansen
hermunn at varnish-software.com
Fri Mar 31 16:27:06 CEST 2017
commit 3c1c9703b1c2b837b9b40eebe3753f53301a545c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Jan 27 20:42:24 2017 +0000
Dramatically simplify VEV
Fixes: #2200
diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc
index df4767b..ba0ec1e 100644
--- a/bin/varnishtest/tests/c00057.vtc
+++ b/bin/varnishtest/tests/c00057.vtc
@@ -18,6 +18,6 @@ client c1 {
txreq
} -run
-delay 5
+delay 7
varnish v1 -cliok "panic.show"
diff --git a/include/vev.h b/include/vev.h
index 37db60f..47fd050 100644
--- a/include/vev.h
+++ b/include/vev.h
@@ -41,6 +41,7 @@ struct vev {
const char *name;
int fd;
unsigned fd_flags;
+ unsigned fd_events;
#define EV_RD POLLIN
#define EV_WR POLLOUT
#define EV_ERR POLLERR
@@ -54,11 +55,9 @@ struct vev {
/* priv */
double __when;
- VTAILQ_ENTRY(vev) __list;
unsigned __binheap_idx;
unsigned __privflags;
struct vev_base *__vevb;
- int __poll_idx;
};
struct vev_base *vev_new_base(void);
diff --git a/lib/libvarnish/vev.c b/lib/libvarnish/vev.c
index 0ceaaa9..760fbed 100644
--- a/lib/libvarnish/vev.c
+++ b/lib/libvarnish/vev.c
@@ -43,7 +43,6 @@
#include "vas.h"
#include "binary_heap.h"
-#include "vqueue.h"
#include "vev.h"
#include "vtim.h"
@@ -67,13 +66,11 @@ static int vev_nsig;
struct vev_base {
unsigned magic;
#define VEV_BASE_MAGIC 0x477bcf3d
- VTAILQ_HEAD(,vev) events;
struct pollfd *pfd;
+ struct vev **pev;
unsigned npfd;
unsigned lpfd;
struct binheap *binheap;
- unsigned char compact_pfd;
- unsigned char disturbed;
unsigned psig;
pthread_t thread;
#ifdef DEBUG_EVENTS
@@ -90,6 +87,7 @@ struct vev_base {
} while (0);
#else
#define DBG(evb, ...) /* ... */
+//#define DBG(evb, ...) fprintf(stderr, __VA_ARGS__);
#endif
/*--------------------------------------------------------------------*/
@@ -102,7 +100,14 @@ vev_bh_update(void *priv, void *a, unsigned u)
CAST_OBJ_NOTNULL(evb, priv, VEV_BASE_MAGIC);
CAST_OBJ_NOTNULL(e, a, VEV_MAGIC);
+ assert(u < evb->lpfd);
e->__binheap_idx = u;
+ if (u != BINHEAP_NOIDX) {
+ evb->pev[u] = e;
+ evb->pfd[u].fd = e->fd;
+ evb->pfd[u].events =
+ e->fd_flags & (EV_RD|EV_WR|EV_ERR|EV_HUP);
+ }
}
static int __match_proto__(binheap_cmp_t)
@@ -123,7 +128,6 @@ static int
vev_get_pfd(struct vev_base *evb)
{
unsigned u;
- void *p;
if (evb->lpfd + 1 < evb->npfd)
return (0);
@@ -134,11 +138,11 @@ vev_get_pfd(struct vev_base *evb)
u = evb->npfd + 256;
else
u = evb->npfd * 2;
- p = realloc(evb->pfd, sizeof *evb->pfd * u);
- if (p == NULL)
- return (1);
evb->npfd = u;
- evb->pfd = p;
+ evb->pfd = realloc(evb->pfd, sizeof(*evb->pfd) * u);
+ AN(evb->pfd);
+ evb->pev = realloc(evb->pev, sizeof(*evb->pev) * u);
+ AN(evb->pev);
return (0);
}
@@ -190,12 +194,12 @@ vev_new_base(void)
evb = calloc(sizeof *evb, 1);
if (evb == NULL)
return (evb);
+ evb->lpfd = BINHEAP_NOIDX + 1;
if (vev_get_pfd(evb)) {
free(evb);
return (NULL);
}
evb->magic = VEV_BASE_MAGIC;
- VTAILQ_INIT(&evb->events);
evb->binheap = binheap_new(evb, vev_bh_cmp, vev_bh_update);
evb->thread = pthread_self();
#ifdef DEBUG_EVENTS
@@ -248,13 +252,14 @@ vev_add(struct vev_base *evb, struct vev *e)
assert(evb->thread == pthread_self());
DBG(evb, "ev_add(%p) fd = %d\n", e, e->fd);
- if (e->sig > 0 && vev_get_sig(e->sig))
- return (ENOMEM);
-
- if (e->fd >= 0 && vev_get_pfd(evb))
+ if (vev_get_pfd(evb))
return (ENOMEM);
if (e->sig > 0) {
+ if (vev_get_sig(e->sig))
+ return (ENOMEM);
+
+ assert(e->fd < 0);
es = &vev_sigs[e->sig];
if (es->vev != NULL)
return (EBUSY);
@@ -267,36 +272,19 @@ vev_add(struct vev_base *evb, struct vev *e)
es = NULL;
}
- if (e->fd >= 0) {
- assert(evb->lpfd < evb->npfd);
- evb->pfd[evb->lpfd].fd = e->fd;
- evb->pfd[evb->lpfd].events =
- e->fd_flags & (EV_RD|EV_WR|EV_ERR|EV_HUP);
- e->__poll_idx = evb->lpfd;
- evb->lpfd++;
- DBG(evb, "... pidx = %d lpfd = %d\n",
- e->__poll_idx, evb->lpfd);
- } else
- e->__poll_idx = -1;
-
e->magic = VEV_MAGIC; /* before binheap_insert() */
- if (e->timeout != 0.0) {
+ if (e->timeout != 0.0)
e->__when += VTIM_mono() + e->timeout;
- binheap_insert(evb->binheap, e);
- assert(e->__binheap_idx > 0);
- DBG(evb, "... bidx = %d\n", e->__binheap_idx);
- } else {
- e->__when = 0.0;
- e->__binheap_idx = 0;
- }
+ else
+ e->__when = 9e99;
+
+ evb->lpfd++;
+ binheap_insert(evb->binheap, e);
+ assert(e->__binheap_idx != BINHEAP_NOIDX);
e->__vevb = evb;
e->__privflags = 0;
- if (e->fd < 0)
- VTAILQ_INSERT_TAIL(&evb->events, e, __list);
- else
- VTAILQ_INSERT_HEAD(&evb->events, e, __list);
if (e->sig > 0) {
assert(es != NULL);
@@ -315,24 +303,16 @@ vev_del(struct vev_base *evb, struct vev *e)
CHECK_OBJ_NOTNULL(evb, VEV_BASE_MAGIC);
CHECK_OBJ_NOTNULL(e, VEV_MAGIC);
- DBG(evb, "ev_del(%p) fd = %d\n", e, e->fd);
+ DBG(evb, "ev_del(%p) fd = %d i=%u L=%d\n", e, e->fd, e->__binheap_idx, evb->lpfd);
assert(evb == e->__vevb);
assert(evb->thread == pthread_self());
+ assert(evb->pev[e->__binheap_idx] == e);
- if (e->__binheap_idx != 0)
- binheap_delete(evb->binheap, e->__binheap_idx);
- AZ(e->__binheap_idx);
-
- if (e->fd >= 0) {
- DBG(evb, "... pidx = %d\n", e->__poll_idx);
- evb->pfd[e->__poll_idx].fd = -1;
- if (e->__poll_idx == evb->lpfd - 1)
- evb->lpfd--;
- else
- evb->compact_pfd++;
- e->fd = -1;
- DBG(evb, "... lpfd = %d\n", evb->lpfd);
- }
+ assert(e->__binheap_idx != BINHEAP_NOIDX);
+ e->fd = -1;
+ binheap_delete(evb->binheap, e->__binheap_idx);
+ assert(e->__binheap_idx == BINHEAP_NOIDX);
+ evb->lpfd--;
if (e->sig > 0) {
assert(e->sig < vev_nsig);
@@ -346,12 +326,8 @@ vev_del(struct vev_base *evb, struct vev *e)
es->happened = 0;
}
- VTAILQ_REMOVE(&evb->events, e, __list);
-
e->magic = 0;
e->__vevb = NULL;
-
- evb->disturbed = 1;
}
/*--------------------------------------------------------------------*/
@@ -371,38 +347,6 @@ vev_schedule(struct vev_base *evb)
/*--------------------------------------------------------------------*/
-static void
-vev_compact_pfd(struct vev_base *evb)
-{
- unsigned u;
- struct pollfd *p;
- struct vev *ep;
- int lfd;
-
- DBG(evb, "compact_pfd() lpfd = %d\n", evb->lpfd);
- p = evb->pfd;
- for (u = 0; u < evb->lpfd; u++, p++) {
- DBG(evb, "...[%d] fd = %d\n", u, p->fd);
- if (p->fd >= 0)
- continue;
- if (u == evb->lpfd - 1)
- break;
- lfd = evb->pfd[evb->lpfd - 1].fd;
- VTAILQ_FOREACH(ep, &evb->events, __list)
- if (ep->fd == lfd)
- break;
- AN(ep);
- DBG(evb, "...[%d] move %p pidx %d\n", u, ep, ep->__poll_idx);
- *p = evb->pfd[--evb->lpfd];
- ep->__poll_idx = u;
- }
- evb->lpfd = u;
- evb->compact_pfd = 0;
- DBG(evb, "... lpfd = %d\n", evb->lpfd);
-}
-
-/*--------------------------------------------------------------------*/
-
static int
vev_sched_timeout(struct vev_base *evb, struct vev *e, double t)
{
@@ -449,16 +393,20 @@ int
vev_schedule_one(struct vev_base *evb)
{
double t;
- struct vev *e, *e2, *e3;
- int i, j, tmo;
- struct pollfd *pfd;
+ struct vev *e;
+ int i, j, k, tmo;
CHECK_OBJ_NOTNULL(evb, VEV_BASE_MAGIC);
assert(evb->thread == pthread_self());
+ assert(evb->lpfd < evb->npfd);
+
+ if (evb->psig)
+ return (vev_sched_signal(evb));
+
e = binheap_root(evb->binheap);
if (e != NULL) {
CHECK_OBJ_NOTNULL(e, VEV_MAGIC);
- assert(e->__binheap_idx == 1);
+ assert(e->__binheap_idx == BINHEAP_NOIDX + 1);
t = VTIM_mono();
if (e->__when <= t)
return (vev_sched_timeout(evb, e, t));
@@ -468,54 +416,43 @@ vev_schedule_one(struct vev_base *evb)
} else
tmo = INFTIM;
- if (evb->compact_pfd)
- vev_compact_pfd(evb);
-
- if (tmo == INFTIM && evb->lpfd == 0)
+ if (tmo == INFTIM && evb->lpfd == BINHEAP_NOIDX + 1)
return (0);
- if (evb->psig)
- return (vev_sched_signal(evb));
- assert(evb->lpfd < evb->npfd);
- i = poll(evb->pfd, evb->lpfd, tmo);
+ i = poll(evb->pfd + 1, evb->lpfd - 1, tmo);
if (i == -1 && errno == EINTR)
return (vev_sched_signal(evb));
+
if (i == 0) {
assert(e != NULL);
t = VTIM_mono();
if (e->__when <= t)
return (vev_sched_timeout(evb, e, t));
}
- evb->disturbed = 0;
- VTAILQ_FOREACH_SAFE(e, &evb->events, __list, e2) {
- if (i == 0)
- break;
- if (e->fd < 0)
- continue;
- assert(e->__poll_idx < evb->lpfd);
- pfd = &evb->pfd[e->__poll_idx];
- assert(pfd->fd == e->fd);
- if (!pfd->revents)
- continue;
- DBG(evb, "callback(%p) fd = %d what = 0x%x pidx = %d\n",
- e, e->fd, pfd->revents, e->__poll_idx);
- j = e->callback(e, pfd->revents);
- i--;
- if (evb->disturbed) {
- VTAILQ_FOREACH(e3, &evb->events, __list) {
- if (e3 == e) {
- e3 = VTAILQ_NEXT(e, __list);
- break;
- } else if (e3 == e2)
- break;
+
+ k = 0;
+ for(j = 1; j < evb->lpfd; j++) {
+ evb->pev[j]->fd_events = evb->pfd[j].revents;
+ if (evb->pev[j]->fd_events)
+ k++;
+ }
+ assert(k == i);
+
+ DBG(evb, "EVENTS %d\n", i);
+ while (i > 0) {
+ for(j = BINHEAP_NOIDX + 1; j < evb->lpfd; j++) {
+ e = evb->pev[j];
+ if (e->fd_events == 0)
+ continue;
+ DBG(evb, "EVENT %p j=%d fd=%d ev=0x%x %d\n",
+ e, j, e->fd, e->fd_events, i);
+ k = e->callback(e, e->fd_events);
+ e->fd_events = 0;
+ i--;
+ if (k) {
+ vev_del(evb, e);
+ free(e);
}
- e2 = e3;
- evb->disturbed = 0;
- }
- if (j) {
- vev_del(evb, e);
- evb->disturbed = 0;
- free(e);
}
}
AZ(i);
More information about the varnish-commit
mailing list