Commit 255f02cf authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move inserts into the binheap into the expiry-thread.

This should make object creation faster.

As a sideeffect, we loose the $expiry_sleep parameter:  Now we always
sleep optimally.
parent 842e4008
...@@ -434,7 +434,7 @@ struct objcore { ...@@ -434,7 +434,7 @@ struct objcore {
unsigned flags; unsigned flags;
#define OC_F_BUSY (1<<1) #define OC_F_BUSY (1<<1)
#define OC_F_PASS (1<<2) #define OC_F_PASS (1<<2)
// #define OC_F_LRUDONTMOVE (1<<4) #define OC_F_OFFLRU (1<<4)
#define OC_F_PRIV (1<<5) /* Stevedore private flag */ #define OC_F_PRIV (1<<5) /* Stevedore private flag */
#define OC_F_LURK (3<<6) /* Ban-lurker-color */ #define OC_F_LURK (3<<6) /* Ban-lurker-color */
#define OC_F_PRIVATE (1<<8) #define OC_F_PRIVATE (1<<8)
......
...@@ -54,6 +54,7 @@ struct exp_priv { ...@@ -54,6 +54,7 @@ struct exp_priv {
struct lock mtx; struct lock mtx;
VTAILQ_HEAD(,objcore) inbox; VTAILQ_HEAD(,objcore) inbox;
struct binheap *heap; struct binheap *heap;
pthread_cond_t condvar;
}; };
static struct exp_priv *exphdl; static struct exp_priv *exphdl;
...@@ -111,22 +112,6 @@ update_object_when(const struct object *o) ...@@ -111,22 +112,6 @@ update_object_when(const struct object *o)
return (1); return (1);
} }
/*--------------------------------------------------------------------*/
static void
exp_insert(struct objcore *oc, struct lru *lru)
{
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
Lck_AssertHeld(&lru->mtx);
Lck_AssertHeld(&exphdl->mtx);
assert(oc->timer_idx == BINHEAP_NOIDX);
binheap_insert(exphdl->heap, oc);
assert(oc->timer_idx != BINHEAP_NOIDX);
VTAILQ_INSERT_TAIL(&lru->lru_head, oc, lru_list);
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Object has been added to cache, record in lru & binheap. * Object has been added to cache, record in lru & binheap.
* *
...@@ -141,11 +126,15 @@ EXP_Inject(struct objcore *oc, struct lru *lru, double when) ...@@ -141,11 +126,15 @@ EXP_Inject(struct objcore *oc, struct lru *lru, double when)
CHECK_OBJ_NOTNULL(lru, LRU_MAGIC); CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
Lck_Lock(&lru->mtx); Lck_Lock(&lru->mtx);
lru->n_objcore++;
Lck_Unlock(&lru->mtx);
Lck_Lock(&exphdl->mtx); Lck_Lock(&exphdl->mtx);
oc->timer_when = when; oc->timer_when = when;
exp_insert(oc, lru); oc->flags |= OC_F_OFFLRU;
VTAILQ_INSERT_TAIL(&exphdl->inbox, oc, lru_list);
AZ(pthread_cond_signal(&exphdl->condvar));
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&exphdl->mtx);
Lck_Unlock(&lru->mtx);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -172,11 +161,16 @@ EXP_Insert(const struct object *o, double now) ...@@ -172,11 +161,16 @@ EXP_Insert(const struct object *o, double now)
lru = oc_getlru(oc); lru = oc_getlru(oc);
CHECK_OBJ_NOTNULL(lru, LRU_MAGIC); CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
Lck_Lock(&lru->mtx); Lck_Lock(&lru->mtx);
lru->n_objcore++;
Lck_Unlock(&lru->mtx);
Lck_Lock(&exphdl->mtx); Lck_Lock(&exphdl->mtx);
(void)update_object_when(o); (void)update_object_when(o);
exp_insert(oc, lru); oc->flags |= OC_F_OFFLRU;
VTAILQ_INSERT_TAIL(&exphdl->inbox, oc, lru_list);
AZ(pthread_cond_signal(&exphdl->condvar));
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&exphdl->mtx);
Lck_Unlock(&lru->mtx);
oc_updatemeta(oc); oc_updatemeta(oc);
} }
...@@ -214,7 +208,9 @@ EXP_Touch(struct objcore *oc) ...@@ -214,7 +208,9 @@ EXP_Touch(struct objcore *oc)
if (Lck_Trylock(&lru->mtx)) if (Lck_Trylock(&lru->mtx))
return (0); return (0);
if (oc->timer_idx != BINHEAP_NOIDX) { if (oc->flags & OC_F_OFFLRU) {
/* Cannot move it while it's in the inbox */
} else if (oc->timer_idx != BINHEAP_NOIDX) {
VTAILQ_REMOVE(&lru->lru_head, oc, lru_list); VTAILQ_REMOVE(&lru->lru_head, oc, lru_list);
VTAILQ_INSERT_TAIL(&lru->lru_head, oc, lru_list); VTAILQ_INSERT_TAIL(&lru->lru_head, oc, lru_list);
VSC_C_main->n_lru_moved++; VSC_C_main->n_lru_moved++;
...@@ -254,6 +250,7 @@ EXP_Rearm(const struct object *o) ...@@ -254,6 +250,7 @@ EXP_Rearm(const struct object *o)
assert(oc->timer_idx != BINHEAP_NOIDX); assert(oc->timer_idx != BINHEAP_NOIDX);
binheap_reorder(exphdl->heap, oc->timer_idx); binheap_reorder(exphdl->heap, oc->timer_idx);
assert(oc->timer_idx != BINHEAP_NOIDX); assert(oc->timer_idx != BINHEAP_NOIDX);
AZ(pthread_cond_signal(&exphdl->condvar)); // XXX
} }
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&exphdl->mtx);
Lck_Unlock(&lru->mtx); Lck_Unlock(&lru->mtx);
...@@ -274,24 +271,55 @@ exp_timer(struct worker *wrk, void *priv) ...@@ -274,24 +271,55 @@ exp_timer(struct worker *wrk, void *priv)
struct object *o; struct object *o;
struct vsl_log vsl; struct vsl_log vsl;
struct exp_priv *ep; struct exp_priv *ep;
struct timespec ts;
int idle;
CAST_OBJ_NOTNULL(ep, priv, EXP_PRIV_MAGIC); CAST_OBJ_NOTNULL(ep, priv, EXP_PRIV_MAGIC);
VSL_Setup(&vsl, NULL, 0); VSL_Setup(&vsl, NULL, 0);
t = VTIM_real(); t = VTIM_real();
oc = NULL; oc = NULL;
idle = 0;
while (1) { while (1) {
if (oc == NULL) { Lck_Lock(&ep->mtx);
if (idle) {
VSL_Flush(&vsl, 0); VSL_Flush(&vsl, 0);
WRK_SumStat(wrk); WRK_SumStat(wrk);
VTIM_sleep(cache_param->expiry_sleep); oc = binheap_root(ep->heap);
if (oc != NULL && oc->timer_when > 0.0) {
ts.tv_nsec = modf(oc->timer_when, &t) * 1e9;
ts.tv_sec = t;
(void)Lck_CondWait(&ep->condvar, &ep->mtx, &ts);
} else if (oc == NULL) {
(void)Lck_CondWait(&ep->condvar, &ep->mtx,NULL);
} else {
/* We're behind, don't sleep */
}
t = VTIM_real(); t = VTIM_real();
} }
Lck_Lock(&exphdl->mtx); oc = VTAILQ_FIRST(&ep->inbox);
oc = binheap_root(exphdl->heap); if (oc != NULL) {
VTAILQ_REMOVE(&ep->inbox, oc, lru_list);
assert(oc->timer_idx == BINHEAP_NOIDX);
binheap_insert(exphdl->heap, oc);
assert(oc->timer_idx != BINHEAP_NOIDX);
Lck_Unlock(&ep->mtx);
lru = oc_getlru(oc);
Lck_Lock(&lru->mtx);
VTAILQ_INSERT_TAIL(&lru->lru_head, oc, lru_list);
oc->flags &= ~OC_F_OFFLRU;
oc->last_lru = t;
Lck_Unlock(&lru->mtx);
idle = 0;
continue;
}
oc = binheap_root(ep->heap);
if (oc == NULL) { if (oc == NULL) {
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&ep->mtx);
idle = 1;
continue; continue;
} }
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
...@@ -303,22 +331,22 @@ exp_timer(struct worker *wrk, void *priv) ...@@ -303,22 +331,22 @@ exp_timer(struct worker *wrk, void *priv)
if (oc->timer_when > t) if (oc->timer_when > t)
t = VTIM_real(); t = VTIM_real();
if (oc->timer_when > t) { if (oc->timer_when > t) {
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&ep->mtx);
oc = NULL; idle = 1;
continue; continue;
} }
/* If the object is busy, we have to wait for it */ /* If the object is busy, we have to wait for it */
if (oc->flags & OC_F_BUSY) { if (oc->flags & OC_F_BUSY) {
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&ep->mtx);
oc = NULL; idle = 1;
continue; continue;
} }
/* /*
* It's time... * It's time...
* Technically we should drop the exphdl->mtx, get the lru->mtx * Technically we should drop the ep->mtx, get the lru->mtx
* get the exphdl->mtx again and then check that the oc is still * get the ep->mtx again and then check that the oc is still
* on the binheap. We take the shorter route and try to * on the binheap. We take the shorter route and try to
* get the lru->mtx and punt if we fail. * get the lru->mtx and punt if we fail.
*/ */
...@@ -326,21 +354,21 @@ exp_timer(struct worker *wrk, void *priv) ...@@ -326,21 +354,21 @@ exp_timer(struct worker *wrk, void *priv)
lru = oc_getlru(oc); lru = oc_getlru(oc);
CHECK_OBJ_NOTNULL(lru, LRU_MAGIC); CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
if (Lck_Trylock(&lru->mtx)) { if (Lck_Trylock(&lru->mtx)) {
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&ep->mtx);
oc = NULL; idle = 1;
continue; continue;
} }
/* Remove from binheap */ /* Remove from binheap */
assert(oc->timer_idx != BINHEAP_NOIDX); assert(oc->timer_idx != BINHEAP_NOIDX);
binheap_delete(exphdl->heap, oc->timer_idx); binheap_delete(ep->heap, oc->timer_idx);
assert(oc->timer_idx == BINHEAP_NOIDX); assert(oc->timer_idx == BINHEAP_NOIDX);
/* And from LRU */ /* And from LRU */
lru = oc_getlru(oc); lru = oc_getlru(oc);
VTAILQ_REMOVE(&lru->lru_head, oc, lru_list); VTAILQ_REMOVE(&lru->lru_head, oc, lru_list);
Lck_Unlock(&exphdl->mtx); Lck_Unlock(&ep->mtx);
Lck_Unlock(&lru->mtx); Lck_Unlock(&lru->mtx);
VSC_C_main->n_expired++; VSC_C_main->n_expired++;
...@@ -499,6 +527,7 @@ EXP_Init(void) ...@@ -499,6 +527,7 @@ EXP_Init(void)
AN(ep); AN(ep);
Lck_New(&ep->mtx, lck_exp); Lck_New(&ep->mtx, lck_exp);
AZ(pthread_cond_init(&ep->condvar, NULL));
ep->heap = binheap_new(NULL, object_cmp, object_update); ep->heap = binheap_new(NULL, object_cmp, object_update);
AN(ep->heap); AN(ep->heap);
VTAILQ_INIT(&ep->inbox); VTAILQ_INIT(&ep->inbox);
......
...@@ -174,9 +174,6 @@ struct params { ...@@ -174,9 +174,6 @@ struct params {
/* Acceptable clockskew with backends */ /* Acceptable clockskew with backends */
unsigned clock_skew; unsigned clock_skew;
/* Expiry pacer parameters */
double expiry_sleep;
/* Acceptor pacer parameters */ /* Acceptor pacer parameters */
double acceptor_sleep_max; double acceptor_sleep_max;
double acceptor_sleep_incr; double acceptor_sleep_incr;
......
...@@ -173,11 +173,6 @@ const struct parspec mgt_parspec[] = { ...@@ -173,11 +173,6 @@ const struct parspec mgt_parspec[] = {
" from first non-white-space character to double CRNL.", " from first non-white-space character to double CRNL.",
0, 0,
"2", "seconds" }, "2", "seconds" },
{ "expiry_sleep", tweak_timeout_double, &mgt_param.expiry_sleep, 0, 60,
"How long the expiry thread sleeps when there is nothing "
"for it to do.\n",
0,
"1", "seconds" },
{ "pipe_timeout", tweak_timeout, &mgt_param.pipe_timeout, 0, 0, { "pipe_timeout", tweak_timeout, &mgt_param.pipe_timeout, 0, 0,
"Idle timeout for PIPE sessions. " "Idle timeout for PIPE sessions. "
"If nothing have been received in either direction for " "If nothing have been received in either direction for "
......
...@@ -18,7 +18,7 @@ server s1 { ...@@ -18,7 +18,7 @@ server s1 {
txresp -bodylen 1025 txresp -bodylen 1025
} -start } -start
varnish v1 -arg "-p expiry_sleep=0.01 -p nuke_limit=0 -p shortlived=0" \ varnish v1 -arg "-p nuke_limit=0 -p shortlived=0" \
-storage "-smalloc,1m" -vcl+backend { -storage "-smalloc,1m" -vcl+backend {
sub vcl_backend_response { sub vcl_backend_response {
set beresp.do_stream = false; set beresp.do_stream = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment