Commit 29e24c34 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Fix #315:

Rename worker->used to worker->lastused and make it an optimization to
set it from a convenient timestamp along the way.

If it is not set when the thread goes on the unemployment queue, expend
a timestamp on setting it.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3182 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 686dca51
...@@ -175,7 +175,7 @@ struct worker { ...@@ -175,7 +175,7 @@ struct worker {
struct objhead *nobjhead; struct objhead *nobjhead;
struct object *nobj; struct object *nobj;
double used; double lastused;
pthread_cond_t cond; pthread_cond_t cond;
......
...@@ -218,8 +218,7 @@ cnt_done(struct sess *sp) ...@@ -218,8 +218,7 @@ cnt_done(struct sess *sp)
} }
sp->t_end = TIM_real(); sp->t_end = TIM_real();
sp->wrk->used = sp->t_end; sp->wrk->lastused = sp->t_end;
assert(!isnan(sp->wrk->used));
if (sp->xid == 0) { if (sp->xid == 0) {
sp->t_req = sp->t_end; sp->t_req = sp->t_end;
sp->t_resp = sp->t_end; sp->t_resp = sp->t_end;
...@@ -236,10 +235,8 @@ cnt_done(struct sess *sp) ...@@ -236,10 +235,8 @@ cnt_done(struct sess *sp)
WSL_Flush(sp->wrk, 0); WSL_Flush(sp->wrk, 0);
/* If we did an ESI include, don't mess up our state */ /* If we did an ESI include, don't mess up our state */
if (sp->esis > 0) { if (sp->esis > 0)
assert(!isnan(sp->wrk->used));
return (1); return (1);
}
sp->t_req = NAN; sp->t_req = NAN;
...@@ -248,7 +245,6 @@ cnt_done(struct sess *sp) ...@@ -248,7 +245,6 @@ cnt_done(struct sess *sp)
if (sp->fd < 0) { if (sp->fd < 0) {
SES_Charge(sp); SES_Charge(sp);
VSL_stats->sess_closed++; VSL_stats->sess_closed++;
assert(!isnan(sp->wrk->used));
sp->wrk = NULL; sp->wrk = NULL;
SES_Delete(sp); SES_Delete(sp);
return (1); return (1);
...@@ -281,7 +277,6 @@ cnt_done(struct sess *sp) ...@@ -281,7 +277,6 @@ cnt_done(struct sess *sp)
} }
VSL_stats->sess_herd++; VSL_stats->sess_herd++;
SES_Charge(sp); SES_Charge(sp);
assert(!isnan(sp->wrk->used));
sp->wrk = NULL; sp->wrk = NULL;
vca_return_session(sp); vca_return_session(sp);
return (1); return (1);
...@@ -465,8 +460,7 @@ cnt_first(struct sess *sp) ...@@ -465,8 +460,7 @@ cnt_first(struct sess *sp)
/* Receive a HTTP protocol request */ /* Receive a HTTP protocol request */
HTC_Init(sp->htc, sp->ws, sp->fd); HTC_Init(sp->htc, sp->ws, sp->fd);
sp->wrk->used = sp->t_open; sp->wrk->lastused = sp->t_open;
assert(!isnan(sp->wrk->used));
sp->wrk->acct.sess++; sp->wrk->acct.sess++;
SES_RefSrcAddr(sp); SES_RefSrcAddr(sp);
do do
...@@ -618,13 +612,6 @@ cnt_lookup(struct sess *sp) ...@@ -618,13 +612,6 @@ cnt_lookup(struct sess *sp)
if (params->diag_bitmap & 0x20) if (params->diag_bitmap & 0x20)
WSP(sp, SLT_Debug, WSP(sp, SLT_Debug,
"on waiting list <%s>", sp->objhead->hash); "on waiting list <%s>", sp->objhead->hash);
/*
* There is a non-zero risk that we come here more than once
* before we get through, in that case cnt_recv must be set
*/
if (isnan(sp->wrk->used))
sp->wrk->used = TIM_real();
assert(!isnan(sp->wrk->used));
SES_Charge(sp); SES_Charge(sp);
return (1); return (1);
} }
...@@ -869,7 +856,6 @@ cnt_recv(struct sess *sp) ...@@ -869,7 +856,6 @@ cnt_recv(struct sess *sp)
/* XXX: VSL something */ /* XXX: VSL something */
INCOMPL(); INCOMPL();
sp->step = STP_DONE; sp->step = STP_DONE;
assert(!isnan(sp->wrk->used));
return (1); return (1);
} }
sp->step = STP_PIPE; sp->step = STP_PIPE;
...@@ -908,8 +894,7 @@ cnt_start(struct sess *sp) ...@@ -908,8 +894,7 @@ cnt_start(struct sess *sp)
/* Update stats of various sorts */ /* Update stats of various sorts */
VSL_stats->client_req++; /* XXX not locked */ VSL_stats->client_req++; /* XXX not locked */
sp->t_req = TIM_real(); sp->t_req = TIM_real();
sp->wrk->used = sp->t_req; sp->wrk->lastused = sp->t_req;
assert(!isnan(sp->wrk->used));
sp->wrk->acct.req++; sp->wrk->acct.req++;
/* Assign XID and log */ /* Assign XID and log */
...@@ -976,6 +961,15 @@ CNT_Session(struct sess *sp) ...@@ -976,6 +961,15 @@ CNT_Session(struct sess *sp)
w = sp->wrk; w = sp->wrk;
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
/*
* Possible entrance states
*/
assert(
sp->step == STP_FIRST ||
sp->step == STP_START ||
sp->step == STP_LOOKUP ||
sp->step == STP_RECV);
/* /*
* Whenever we come in from the acceptor we need to set blocking * Whenever we come in from the acceptor we need to set blocking
* mode, but there is no point in setting it when we come from * mode, but there is no point in setting it when we come from
...@@ -1013,7 +1007,6 @@ CNT_Session(struct sess *sp) ...@@ -1013,7 +1007,6 @@ CNT_Session(struct sess *sp)
CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC); CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC);
CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
} }
assert(!isnan(w->used));
WSL_Flush(w, 0); WSL_Flush(w, 0);
} }
......
...@@ -245,7 +245,7 @@ wrk_thread(void *priv) ...@@ -245,7 +245,7 @@ wrk_thread(void *priv)
CAST_OBJ_NOTNULL(qp, priv, WQ_MAGIC); CAST_OBJ_NOTNULL(qp, priv, WQ_MAGIC);
memset(w, 0, sizeof *w); memset(w, 0, sizeof *w);
w->magic = WORKER_MAGIC; w->magic = WORKER_MAGIC;
w->used = TIM_real(); w->lastused = NAN;
w->wlb = w->wlp = wlog; w->wlb = w->wlp = wlog;
w->wle = wlog + sizeof wlog; w->wle = wlog + sizeof wlog;
AZ(pthread_cond_init(&w->cond, NULL)); AZ(pthread_cond_init(&w->cond, NULL));
...@@ -256,7 +256,6 @@ wrk_thread(void *priv) ...@@ -256,7 +256,6 @@ wrk_thread(void *priv)
qp->nthr++; qp->nthr++;
while (1) { while (1) {
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
assert(!isnan(w->used));
/* Process overflow requests, if any */ /* Process overflow requests, if any */
w->wrq = VTAILQ_FIRST(&qp->overflow); w->wrq = VTAILQ_FIRST(&qp->overflow);
...@@ -264,6 +263,8 @@ wrk_thread(void *priv) ...@@ -264,6 +263,8 @@ wrk_thread(void *priv)
VTAILQ_REMOVE(&qp->overflow, w->wrq, list); VTAILQ_REMOVE(&qp->overflow, w->wrq, list);
qp->nqueue--; qp->nqueue--;
} else { } else {
if (isnan(w->lastused))
w->lastused = TIM_real();
VTAILQ_INSERT_HEAD(&qp->idle, w, list); VTAILQ_INSERT_HEAD(&qp->idle, w, list);
AZ(pthread_cond_wait(&w->cond, &qp->mtx)); AZ(pthread_cond_wait(&w->cond, &qp->mtx));
} }
...@@ -273,6 +274,7 @@ wrk_thread(void *priv) ...@@ -273,6 +274,7 @@ wrk_thread(void *priv)
AN(w->wrq); AN(w->wrq);
wrq = w->wrq; wrq = w->wrq;
AN(wrq->func); AN(wrq->func);
w->lastused = NAN;
wrq->func(w, wrq->priv); wrq->func(w, wrq->priv);
w->wrq = NULL; w->wrq = NULL;
LOCK(&qp->mtx); LOCK(&qp->mtx);
...@@ -359,9 +361,7 @@ wrk_do_cnt_sess(struct worker *w, void *priv) ...@@ -359,9 +361,7 @@ wrk_do_cnt_sess(struct worker *w, void *priv)
sess->wrk = w; sess->wrk = w;
CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC); CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC);
CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
w->used = NAN;
CNT_Session(sess); CNT_Session(sess);
assert(!isnan(w->used));
CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC); CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC);
CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
THR_SetSession(NULL); THR_SetSession(NULL);
...@@ -438,7 +438,7 @@ wrk_decimate_flock(struct wq *qp, double t_idle, struct varnish_stats *vs) ...@@ -438,7 +438,7 @@ wrk_decimate_flock(struct wq *qp, double t_idle, struct varnish_stats *vs)
LOCK(&qp->mtx); LOCK(&qp->mtx);
w = VTAILQ_LAST(&qp->idle, workerhead); w = VTAILQ_LAST(&qp->idle, workerhead);
if (w != NULL && (w->used < t_idle || qp->nthr > nthr_max)) if (w != NULL && (w->lastused < t_idle || qp->nthr > nthr_max))
VTAILQ_REMOVE(&qp->idle, w, list); VTAILQ_REMOVE(&qp->idle, w, list);
else else
w = NULL; w = NULL;
......
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