Commit 5c826806 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Integrate the waiting list into the objhead (again). The net saving

of one pointer does not amortize the extra CPU overhead and cache misses.
parent 0be9404f
......@@ -121,7 +121,6 @@ struct sess;
struct suckaddr;
struct vrt_priv;
struct vsb;
struct waitinglist;
struct worker;
struct v1l;
......@@ -329,7 +328,6 @@ struct worker {
struct pool *pool;
struct objhead *nobjhead;
struct objcore *nobjcore;
struct waitinglist *nwaitinglist;
void *nhashpriv;
struct dstat stats[1];
struct vsl_log *vsl; // borrowed from req/bo
......
......@@ -795,7 +795,7 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)
http_TimeHeader(bo->beresp, "Date: ", now);
http_SetHeader(bo->beresp, "Server: Varnish");
if (bo->fetch_objcore->objhead->waitinglist != NULL) {
if (!VTAILQ_EMPTY(&bo->fetch_objcore->objhead->waitinglist)) {
/*
* If there is a waitinglist, it means that there is no
* grace-able object, so cache the error return for a
......
......@@ -90,6 +90,7 @@ hsh_newobjhead(void)
XXXAN(oh);
oh->refcnt = 1;
VTAILQ_INIT(&oh->objcs);
VTAILQ_INIT(&oh->waitinglist);
Lck_New(&oh->mtx, lck_objhdr);
return (oh);
}
......@@ -99,7 +100,6 @@ hsh_newobjhead(void)
static void
hsh_prealloc(struct worker *wrk)
{
struct waitinglist *wl;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
......@@ -113,15 +113,6 @@ hsh_prealloc(struct worker *wrk)
}
CHECK_OBJ_NOTNULL(wrk->nobjhead, OBJHEAD_MAGIC);
if (wrk->nwaitinglist == NULL) {
ALLOC_OBJ(wl, WAITINGLIST_MAGIC);
XXXAN(wl);
VTAILQ_INIT(&wl->list);
wrk->nwaitinglist = wl;
wrk->stats->n_waitinglist++;
}
CHECK_OBJ_NOTNULL(wrk->nwaitinglist, WAITINGLIST_MAGIC);
if (hash->prep != NULL)
hash->prep(wrk);
}
......@@ -163,11 +154,6 @@ HSH_Cleanup(struct worker *wrk)
wrk->nobjhead = NULL;
wrk->stats->n_objecthead--;
}
if (wrk->nwaitinglist != NULL) {
FREE_OBJ(wrk->nwaitinglist);
wrk->nwaitinglist = NULL;
wrk->stats->n_waitinglist--;
}
if (wrk->nhashpriv != NULL) {
/* XXX: If needed, add slinger method for this */
free(wrk->nhashpriv);
......@@ -181,6 +167,7 @@ HSH_DeleteObjHead(struct worker *wrk, struct objhead *oh)
AZ(oh->refcnt);
assert(VTAILQ_EMPTY(&oh->objcs));
assert(VTAILQ_EMPTY(&oh->waitinglist));
Lck_Delete(&oh->mtx);
wrk->stats->n_objecthead--;
FREE_OBJ(oh);
......@@ -482,13 +469,7 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp,
AZ(req->hash_ignore_busy);
if (wait_for_busy) {
CHECK_OBJ_NOTNULL(wrk->nwaitinglist, WAITINGLIST_MAGIC);
if (oh->waitinglist == NULL) {
oh->waitinglist = wrk->nwaitinglist;
wrk->nwaitinglist = NULL;
}
VTAILQ_INSERT_TAIL(&oh->waitinglist->list,
req, w_list);
VTAILQ_INSERT_TAIL(&oh->waitinglist, req, w_list);
if (DO_DEBUG(DBG_WAITINGLIST))
VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh);
} else {
......@@ -517,21 +498,18 @@ hsh_rush(struct worker *wrk, struct objhead *oh)
unsigned u;
struct req *req;
struct sess *sp;
struct waitinglist *wl;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
Lck_AssertHeld(&oh->mtx);
wl = oh->waitinglist;
CHECK_OBJ_NOTNULL(wl, WAITINGLIST_MAGIC);
for (u = 0; u < cache_param->rush_exponent; u++) {
req = VTAILQ_FIRST(&wl->list);
req = VTAILQ_FIRST(&oh->waitinglist);
if (req == NULL)
break;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
wrk->stats->busy_wakeup++;
AZ(req->wrk);
VTAILQ_REMOVE(&wl->list, req, w_list);
VTAILQ_REMOVE(&oh->waitinglist, req, w_list);
DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list");
if (SES_Reschedule_Req(req)) {
/*
......@@ -548,22 +526,17 @@ hsh_rush(struct worker *wrk, struct objhead *oh)
CNT_AcctLogCharge(wrk->stats, req);
Req_Release(req);
SES_Delete(sp, SC_OVERLOAD, NAN);
req = VTAILQ_FIRST(&wl->list);
req = VTAILQ_FIRST(&oh->waitinglist);
if (req == NULL)
break;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
VTAILQ_REMOVE(&wl->list, req, w_list);
VTAILQ_REMOVE(&oh->waitinglist, req, w_list);
DSL(DBG_WAITINGLIST, req->vsl->wid,
"kill from waiting list");
}
break;
}
}
if (VTAILQ_EMPTY(&wl->list)) {
oh->waitinglist = NULL;
FREE_OBJ(wl);
wrk->stats->n_waitinglist--;
}
}
/*---------------------------------------------------------------------
......@@ -706,7 +679,7 @@ HSH_Unbusy(struct worker *wrk, struct objcore *oc)
VTAILQ_REMOVE(&oh->objcs, oc, list);
VTAILQ_INSERT_HEAD(&oh->objcs, oc, list);
oc->flags &= ~OC_F_BUSY;
if (oh->waitinglist != NULL)
if (!VTAILQ_EMPTY(&oh->waitinglist))
hsh_rush(wrk, oh);
Lck_Unlock(&oh->mtx);
}
......@@ -781,7 +754,7 @@ HSH_DerefObjCore(struct worker *wrk, struct objcore **ocp)
r = --oc->refcnt;
if (!r)
VTAILQ_REMOVE(&oh->objcs, oc, list);
if (oh->waitinglist != NULL)
if (!VTAILQ_EMPTY(&oh->waitinglist))
hsh_rush(wrk, oh);
Lck_Unlock(&oh->mtx);
if (r != 0)
......@@ -814,13 +787,13 @@ HSH_DerefObjHead(struct worker *wrk, struct objhead **poh)
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (oh == private_oh) {
AZ(oh->waitinglist);
assert(VTAILQ_EMPTY(&oh->waitinglist));
Lck_Lock(&oh->mtx);
assert(oh->refcnt > 1);
oh->refcnt--;
Lck_Unlock(&oh->mtx);
return(1);
} else if (oh->waitinglist != NULL) {
} else if (!VTAILQ_EMPTY(&oh->waitinglist)) {
Lck_Lock(&oh->mtx);
hsh_rush(wrk, oh);
Lck_Unlock(&oh->mtx);
......
......@@ -406,8 +406,6 @@ hcb_deref(struct objhead *oh)
hcb_delete(&hcb_root, oh);
VTAILQ_INSERT_TAIL(&cool_h, oh, hoh_list);
Lck_Unlock(&hcb_mtx);
assert(VTAILQ_EMPTY(&oh->objcs));
AZ(oh->waitinglist);
}
Lck_Unlock(&oh->mtx);
#ifdef PHK
......
......@@ -77,12 +77,6 @@ struct objcore *HSH_Private(struct worker *wrk);
#ifdef VARNISH_CACHE_CHILD
struct waitinglist {
unsigned magic;
#define WAITINGLIST_MAGIC 0x063a477a
VTAILQ_HEAD(, req) list;
};
struct objhead {
unsigned magic;
#define OBJHEAD_MAGIC 0x1b96615d
......@@ -91,7 +85,7 @@ struct objhead {
struct lock mtx;
VTAILQ_HEAD(,objcore) objcs;
uint8_t digest[DIGEST_LEN];
struct waitinglist *waitinglist;
VTAILQ_HEAD(, req) waitinglist;
/*----------------------------------------------------
* The fields below are for the sole private use of
......
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