From: phk Date: Thu, 12 Feb 2009 17:23:16 +0000 (+0000) Subject: Move objcore over objects, so that objhead has a list of objcore X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f930dbc45b083bb9f462ff7886e6d533c8ccae1f;p=varnish Move objcore over objects, so that objhead has a list of objcore which point to the objects. Preallocate objcore with obj+objhead before we enter locked hash sections. Rename objcore.list to objcore.lru_list. Eliminate obj.list and objhead.hashlen git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3756 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index d88976d1..e8486542 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -183,6 +183,7 @@ struct worker { #define WORKER_MAGIC 0x6391adcf struct objhead *nobjhead; struct object *nobj; + struct objcore *nobjcore; double lastused; @@ -264,6 +265,7 @@ struct objcore { const char *timer_what; unsigned timer_idx; VTAILQ_ENTRY(objcore) list; + VTAILQ_ENTRY(objcore) lru_list; int on_lru; double lru_stamp; }; @@ -302,7 +304,6 @@ struct object { double last_modified; struct http http[1]; - VTAILQ_ENTRY(object) list; VTAILQ_HEAD(, storage) store; diff --git a/varnish-cache/bin/varnishd/cache_cli.c b/varnish-cache/bin/varnishd/cache_cli.c index 7ecef6d7..648ebd8a 100644 --- a/varnish-cache/bin/varnishd/cache_cli.c +++ b/varnish-cache/bin/varnishd/cache_cli.c @@ -197,6 +197,7 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) SZOF(struct sess); SZOF(struct vbe_conn); SZOF(struct varnish_stats); + SZOF(struct lock); } /*--------------------------------------------------------------------*/ diff --git a/varnish-cache/bin/varnishd/cache_expire.c b/varnish-cache/bin/varnishd/cache_expire.c index b33c4c02..315b65ea 100644 --- a/varnish-cache/bin/varnishd/cache_expire.c +++ b/varnish-cache/bin/varnishd/cache_expire.c @@ -78,37 +78,6 @@ static VTAILQ_HEAD(,objcore) lru = VTAILQ_HEAD_INITIALIZER(lru); */ #define BINHEAP_NOIDX 0 -/*-------------------------------------------------------------------- - * Add and Remove objcore's from objects. - */ - -static void -add_objcore(struct object *o) -{ - - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - AZ(o->objcore); - assert(o->busy); - assert(o->cacheable); - o->objcore = calloc(sizeof *o->objcore, 1); - AN(o->objcore); - o->objcore->magic = OBJCORE_MAGIC; - o->objcore->obj = o; -} - -static void -del_objcore(struct object *o) -{ - struct objcore *oc; - - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - oc = o->objcore; - o->objcore = NULL; - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - assert(oc->timer_idx == BINHEAP_NOIDX); - free(oc); -} - /*-------------------------------------------------------------------- * When & why does the timer fire for this object ? */ @@ -160,7 +129,7 @@ EXP_Insert(struct object *o) assert(o->busy); assert(o->cacheable); HSH_Ref(o); - add_objcore(o); + CHECK_OBJ_NOTNULL(o->objcore, OBJCORE_MAGIC); oc = o->objcore; assert(o->entered != 0 && !isnan(o->entered)); @@ -170,7 +139,7 @@ EXP_Insert(struct object *o) (void)update_object_when(o); binheap_insert(exp_heap, oc); assert(oc->timer_idx != BINHEAP_NOIDX); - VTAILQ_INSERT_TAIL(&lru, oc, list); + VTAILQ_INSERT_TAIL(&lru, oc, lru_list); oc->on_lru = 1; Lck_Unlock(&exp_mtx); } @@ -199,8 +168,8 @@ EXP_Touch(const struct object *o, double now) if (Lck_Trylock(&exp_mtx)) return; if (oc->on_lru) { - VTAILQ_REMOVE(&lru, oc, list); - VTAILQ_INSERT_TAIL(&lru, oc, list); + VTAILQ_REMOVE(&lru, oc, lru_list); + VTAILQ_INSERT_TAIL(&lru, oc, lru_list); oc->lru_stamp = now; VSL_stats->n_lru_moved++; } @@ -335,11 +304,10 @@ exp_timer(void *arg) "%u %d", o->xid, (int)(o->ttl - t)); Lck_Lock(&exp_mtx); assert(oc->timer_idx == BINHEAP_NOIDX); - VTAILQ_REMOVE(&lru, o->objcore, list); + VTAILQ_REMOVE(&lru, o->objcore, lru_list); oc->on_lru = 0; VSL_stats->n_expired++; Lck_Unlock(&exp_mtx); - del_objcore(o); HSH_Deref(&o); } } @@ -370,7 +338,7 @@ EXP_NukeOne(struct sess *sp) * another ref while we ponder its destiny without the lock held. */ Lck_Lock(&exp_mtx); - VTAILQ_FOREACH(oc, &lru, list) { + VTAILQ_FOREACH(oc, &lru, lru_list) { CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); if (oc->timer_idx == BINHEAP_NOIDX) /* exp_timer has it */ continue; @@ -384,7 +352,7 @@ EXP_NukeOne(struct sess *sp) * a lock cycle. If the object is kept, we reverse these * actions below. */ - VTAILQ_REMOVE(&lru, oc, list); + VTAILQ_REMOVE(&lru, oc, lru_list); oc->on_lru = 0; binheap_delete(exp_heap, oc->timer_idx); assert(oc->timer_idx == BINHEAP_NOIDX); @@ -408,7 +376,6 @@ EXP_NukeOne(struct sess *sp) if (sp->handling == VCL_RET_DISCARD) { WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid); - del_objcore(o); HSH_Deref(&o); return (1); } @@ -421,7 +388,7 @@ EXP_NukeOne(struct sess *sp) VSL_stats->n_lru_saved++; binheap_insert(exp_heap, oc); assert(oc->timer_idx != BINHEAP_NOIDX); - VTAILQ_INSERT_TAIL(&lru, oc, list); + VTAILQ_INSERT_TAIL(&lru, oc, lru_list); oc->on_lru = 1; Lck_Unlock(&exp_mtx); return (0); diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index aec29423..dda20d31 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -85,6 +85,7 @@ HSH_Prealloc(struct sess *sp) { struct worker *w; struct objhead *oh; + struct objcore *oc; struct object *o; struct storage *st; @@ -92,17 +93,23 @@ HSH_Prealloc(struct sess *sp) CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); w = sp->wrk; + if (w->nobjcore == NULL) { + ALLOC_OBJ(oc, OBJCORE_MAGIC); + w->nobjcore = oc; + } + CHECK_OBJ_NOTNULL(w->nobjcore, OBJCORE_MAGIC); + if (w->nobjhead == NULL) { ALLOC_OBJ(oh, OBJHEAD_MAGIC); XXXAN(oh); oh->refcnt = 1; - VTAILQ_INIT(&oh->objects); + VTAILQ_INIT(&oh->objcs); VTAILQ_INIT(&oh->waitinglist); Lck_New(&oh->mtx); w->nobjhead = oh; VSL_stats->n_objecthead++; - } else - CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC); + } + CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC); if (w->nobj == NULL) { st = STV_alloc(sp, params->obj_workspace); @@ -128,8 +135,8 @@ HSH_Prealloc(struct sess *sp) w->nobj = o; VSL_stats->n_object++; - } else - CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC); + } + CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC); } void @@ -157,7 +164,6 @@ HSH_Copy(const struct sess *sp, struct objhead *oh) oh->hash = malloc(sp->lhashptr); XXXAN(oh->hash); - oh->hashlen = sp->lhashptr; b = oh->hash; for (u = 0; u < sp->ihashptr; u += 2) { v = pdiff(sp->hashptr[u], sp->hashptr[u + 1]); @@ -166,7 +172,7 @@ HSH_Copy(const struct sess *sp, struct objhead *oh) *b++ = '#'; } *b++ = '\0'; - assert(b <= oh->hash + oh->hashlen); + assert(b <= oh->hash + sp->lhashptr); } void @@ -229,6 +235,7 @@ HSH_Lookup(struct sess *sp) { struct worker *w; struct objhead *oh; + struct objcore *oc; struct object *o, *busy_o, *grace_o; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -257,7 +264,11 @@ HSH_Lookup(struct sess *sp) busy_o = NULL; grace_o = NULL; - VTAILQ_FOREACH(o, &oh->objects, list) { + o = NULL; + VTAILQ_FOREACH(oc, &oh->objcs, list) { + o = oc->obj; + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + if (o->busy) { busy_o = o; continue; @@ -279,6 +290,10 @@ HSH_Lookup(struct sess *sp) if (o->ttl + HSH_Grace(o->grace) >= sp->t_req) grace_o = o; } + if (oc == NULL) + o = NULL; + else + AN(o); /* * If we have a object in grace and being fetched, @@ -314,9 +329,15 @@ HSH_Lookup(struct sess *sp) /* Insert (precreated) object in objecthead */ o = w->nobj; w->nobj = NULL; + + oc = w->nobjcore; + w->nobjcore = NULL; + o->objhead = oh; + o->objcore = oc; + oc->obj = o; /* XXX: Should this not be ..._HEAD now ? */ - VTAILQ_INSERT_TAIL(&oh->objects, o, list); + VTAILQ_INSERT_TAIL(&oh->objcs, oc, list); /* NB: do not deref objhead the new object inherits our reference */ if (grace_o != NULL) { grace_o->child = o; @@ -419,6 +440,7 @@ HSH_Deref(struct object **oo) { struct object *o; struct objhead *oh; + struct objcore *oc; unsigned r; AN(oo); @@ -426,19 +448,22 @@ HSH_Deref(struct object **oo) *oo = NULL; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); oh = o->objhead; - if (oh != NULL) { + if (oh == NULL) { + oc = NULL; + assert(o->refcnt > 0); + r = --o->refcnt; + } else { CHECK_OBJ(oh, OBJHEAD_MAGIC); - /* drop ref on object */ + oc = o->objcore; + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + Lck_Lock(&oh->mtx); - } - assert(o->refcnt > 0); - r = --o->refcnt; - if (oh != NULL) - hsh_rush(oh); - if (oh != NULL) { + assert(o->refcnt > 0); + r = --o->refcnt; if (!r) - VTAILQ_REMOVE(&oh->objects, o, list); + VTAILQ_REMOVE(&oh->objcs, oc, list); + hsh_rush(oh); Lck_Unlock(&oh->mtx); } @@ -458,12 +483,16 @@ HSH_Deref(struct object **oo) STV_free(o->objstore); VSL_stats->n_object--; - if (oh == NULL) + if (oh == NULL) { + AZ(oc); return; + } + AN(oc); + FREE_OBJ(oc); /* Drop our ref on the objhead */ if (hash->deref(oh)) return; - assert(VTAILQ_EMPTY(&oh->objects)); + assert(VTAILQ_EMPTY(&oh->objcs)); Lck_Delete(&oh->mtx); VSL_stats->n_objecthead--; free(oh->hash); diff --git a/varnish-cache/bin/varnishd/hash_critbit.c b/varnish-cache/bin/varnishd/hash_critbit.c index e37efcca..d43a78ec 100644 --- a/varnish-cache/bin/varnishd/hash_critbit.c +++ b/varnish-cache/bin/varnishd/hash_critbit.c @@ -432,7 +432,6 @@ hcb_lookup(const struct sess *sp, struct objhead *noh) } else { free(noh->hash); noh->hash = NULL; - noh->hashlen = 0; VSL_stats->hcb_lock++; #ifdef PHK fprintf(stderr, "hcb_lookup %d\n", __LINE__); diff --git a/varnish-cache/bin/varnishd/hash_slinger.h b/varnish-cache/bin/varnishd/hash_slinger.h index 85a1b08b..1e797f62 100644 --- a/varnish-cache/bin/varnishd/hash_slinger.h +++ b/varnish-cache/bin/varnishd/hash_slinger.h @@ -73,11 +73,10 @@ struct objhead { struct lock mtx; unsigned refcnt; - VTAILQ_HEAD(,object) objects; + VTAILQ_HEAD(,objcore) objcs; char *hash; - unsigned hashlen; unsigned char digest[DIGEST_LEN]; -#ifdef NOT_YET +#ifndef NOT_YET union { VTAILQ_HEAD(, sess) __u_waitinglist; VTAILQ_ENTRY(objhead) __u_coollist;