Commit 79c70102 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@3756 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent cdaeac8b
...@@ -183,6 +183,7 @@ struct worker { ...@@ -183,6 +183,7 @@ struct worker {
#define WORKER_MAGIC 0x6391adcf #define WORKER_MAGIC 0x6391adcf
struct objhead *nobjhead; struct objhead *nobjhead;
struct object *nobj; struct object *nobj;
struct objcore *nobjcore;
double lastused; double lastused;
...@@ -264,6 +265,7 @@ struct objcore { ...@@ -264,6 +265,7 @@ struct objcore {
const char *timer_what; const char *timer_what;
unsigned timer_idx; unsigned timer_idx;
VTAILQ_ENTRY(objcore) list; VTAILQ_ENTRY(objcore) list;
VTAILQ_ENTRY(objcore) lru_list;
int on_lru; int on_lru;
double lru_stamp; double lru_stamp;
}; };
...@@ -302,7 +304,6 @@ struct object { ...@@ -302,7 +304,6 @@ struct object {
double last_modified; double last_modified;
struct http http[1]; struct http http[1];
VTAILQ_ENTRY(object) list;
VTAILQ_HEAD(, storage) store; VTAILQ_HEAD(, storage) store;
......
...@@ -197,6 +197,7 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) ...@@ -197,6 +197,7 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv)
SZOF(struct sess); SZOF(struct sess);
SZOF(struct vbe_conn); SZOF(struct vbe_conn);
SZOF(struct varnish_stats); SZOF(struct varnish_stats);
SZOF(struct lock);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
......
...@@ -78,37 +78,6 @@ static VTAILQ_HEAD(,objcore) lru = VTAILQ_HEAD_INITIALIZER(lru); ...@@ -78,37 +78,6 @@ static VTAILQ_HEAD(,objcore) lru = VTAILQ_HEAD_INITIALIZER(lru);
*/ */
#define BINHEAP_NOIDX 0 #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 ? * When & why does the timer fire for this object ?
*/ */
...@@ -160,7 +129,7 @@ EXP_Insert(struct object *o) ...@@ -160,7 +129,7 @@ EXP_Insert(struct object *o)
assert(o->busy); assert(o->busy);
assert(o->cacheable); assert(o->cacheable);
HSH_Ref(o); HSH_Ref(o);
add_objcore(o); CHECK_OBJ_NOTNULL(o->objcore, OBJCORE_MAGIC);
oc = o->objcore; oc = o->objcore;
assert(o->entered != 0 && !isnan(o->entered)); assert(o->entered != 0 && !isnan(o->entered));
...@@ -170,7 +139,7 @@ EXP_Insert(struct object *o) ...@@ -170,7 +139,7 @@ EXP_Insert(struct object *o)
(void)update_object_when(o); (void)update_object_when(o);
binheap_insert(exp_heap, oc); binheap_insert(exp_heap, oc);
assert(oc->timer_idx != BINHEAP_NOIDX); assert(oc->timer_idx != BINHEAP_NOIDX);
VTAILQ_INSERT_TAIL(&lru, oc, list); VTAILQ_INSERT_TAIL(&lru, oc, lru_list);
oc->on_lru = 1; oc->on_lru = 1;
Lck_Unlock(&exp_mtx); Lck_Unlock(&exp_mtx);
} }
...@@ -199,8 +168,8 @@ EXP_Touch(const struct object *o, double now) ...@@ -199,8 +168,8 @@ EXP_Touch(const struct object *o, double now)
if (Lck_Trylock(&exp_mtx)) if (Lck_Trylock(&exp_mtx))
return; return;
if (oc->on_lru) { if (oc->on_lru) {
VTAILQ_REMOVE(&lru, oc, list); VTAILQ_REMOVE(&lru, oc, lru_list);
VTAILQ_INSERT_TAIL(&lru, oc, list); VTAILQ_INSERT_TAIL(&lru, oc, lru_list);
oc->lru_stamp = now; oc->lru_stamp = now;
VSL_stats->n_lru_moved++; VSL_stats->n_lru_moved++;
} }
...@@ -335,11 +304,10 @@ exp_timer(void *arg) ...@@ -335,11 +304,10 @@ exp_timer(void *arg)
"%u %d", o->xid, (int)(o->ttl - t)); "%u %d", o->xid, (int)(o->ttl - t));
Lck_Lock(&exp_mtx); Lck_Lock(&exp_mtx);
assert(oc->timer_idx == BINHEAP_NOIDX); assert(oc->timer_idx == BINHEAP_NOIDX);
VTAILQ_REMOVE(&lru, o->objcore, list); VTAILQ_REMOVE(&lru, o->objcore, lru_list);
oc->on_lru = 0; oc->on_lru = 0;
VSL_stats->n_expired++; VSL_stats->n_expired++;
Lck_Unlock(&exp_mtx); Lck_Unlock(&exp_mtx);
del_objcore(o);
HSH_Deref(&o); HSH_Deref(&o);
} }
} }
...@@ -370,7 +338,7 @@ EXP_NukeOne(struct sess *sp) ...@@ -370,7 +338,7 @@ EXP_NukeOne(struct sess *sp)
* another ref while we ponder its destiny without the lock held. * another ref while we ponder its destiny without the lock held.
*/ */
Lck_Lock(&exp_mtx); Lck_Lock(&exp_mtx);
VTAILQ_FOREACH(oc, &lru, list) { VTAILQ_FOREACH(oc, &lru, lru_list) {
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
if (oc->timer_idx == BINHEAP_NOIDX) /* exp_timer has it */ if (oc->timer_idx == BINHEAP_NOIDX) /* exp_timer has it */
continue; continue;
...@@ -384,7 +352,7 @@ EXP_NukeOne(struct sess *sp) ...@@ -384,7 +352,7 @@ EXP_NukeOne(struct sess *sp)
* a lock cycle. If the object is kept, we reverse these * a lock cycle. If the object is kept, we reverse these
* actions below. * actions below.
*/ */
VTAILQ_REMOVE(&lru, oc, list); VTAILQ_REMOVE(&lru, oc, lru_list);
oc->on_lru = 0; oc->on_lru = 0;
binheap_delete(exp_heap, oc->timer_idx); binheap_delete(exp_heap, oc->timer_idx);
assert(oc->timer_idx == BINHEAP_NOIDX); assert(oc->timer_idx == BINHEAP_NOIDX);
...@@ -408,7 +376,6 @@ EXP_NukeOne(struct sess *sp) ...@@ -408,7 +376,6 @@ EXP_NukeOne(struct sess *sp)
if (sp->handling == VCL_RET_DISCARD) { if (sp->handling == VCL_RET_DISCARD) {
WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid); WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid);
del_objcore(o);
HSH_Deref(&o); HSH_Deref(&o);
return (1); return (1);
} }
...@@ -421,7 +388,7 @@ EXP_NukeOne(struct sess *sp) ...@@ -421,7 +388,7 @@ EXP_NukeOne(struct sess *sp)
VSL_stats->n_lru_saved++; VSL_stats->n_lru_saved++;
binheap_insert(exp_heap, oc); binheap_insert(exp_heap, oc);
assert(oc->timer_idx != BINHEAP_NOIDX); assert(oc->timer_idx != BINHEAP_NOIDX);
VTAILQ_INSERT_TAIL(&lru, oc, list); VTAILQ_INSERT_TAIL(&lru, oc, lru_list);
oc->on_lru = 1; oc->on_lru = 1;
Lck_Unlock(&exp_mtx); Lck_Unlock(&exp_mtx);
return (0); return (0);
......
...@@ -85,6 +85,7 @@ HSH_Prealloc(struct sess *sp) ...@@ -85,6 +85,7 @@ HSH_Prealloc(struct sess *sp)
{ {
struct worker *w; struct worker *w;
struct objhead *oh; struct objhead *oh;
struct objcore *oc;
struct object *o; struct object *o;
struct storage *st; struct storage *st;
...@@ -92,17 +93,23 @@ HSH_Prealloc(struct sess *sp) ...@@ -92,17 +93,23 @@ HSH_Prealloc(struct sess *sp)
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
w = sp->wrk; 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) { if (w->nobjhead == NULL) {
ALLOC_OBJ(oh, OBJHEAD_MAGIC); ALLOC_OBJ(oh, OBJHEAD_MAGIC);
XXXAN(oh); XXXAN(oh);
oh->refcnt = 1; oh->refcnt = 1;
VTAILQ_INIT(&oh->objects); VTAILQ_INIT(&oh->objcs);
VTAILQ_INIT(&oh->waitinglist); VTAILQ_INIT(&oh->waitinglist);
Lck_New(&oh->mtx); Lck_New(&oh->mtx);
w->nobjhead = oh; w->nobjhead = oh;
VSL_stats->n_objecthead++; VSL_stats->n_objecthead++;
} else }
CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC);
if (w->nobj == NULL) { if (w->nobj == NULL) {
st = STV_alloc(sp, params->obj_workspace); st = STV_alloc(sp, params->obj_workspace);
...@@ -128,8 +135,8 @@ HSH_Prealloc(struct sess *sp) ...@@ -128,8 +135,8 @@ HSH_Prealloc(struct sess *sp)
w->nobj = o; w->nobj = o;
VSL_stats->n_object++; VSL_stats->n_object++;
} else }
CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
} }
void void
...@@ -157,7 +164,6 @@ HSH_Copy(const struct sess *sp, struct objhead *oh) ...@@ -157,7 +164,6 @@ HSH_Copy(const struct sess *sp, struct objhead *oh)
oh->hash = malloc(sp->lhashptr); oh->hash = malloc(sp->lhashptr);
XXXAN(oh->hash); XXXAN(oh->hash);
oh->hashlen = sp->lhashptr;
b = oh->hash; b = oh->hash;
for (u = 0; u < sp->ihashptr; u += 2) { for (u = 0; u < sp->ihashptr; u += 2) {
v = pdiff(sp->hashptr[u], sp->hashptr[u + 1]); v = pdiff(sp->hashptr[u], sp->hashptr[u + 1]);
...@@ -166,7 +172,7 @@ HSH_Copy(const struct sess *sp, struct objhead *oh) ...@@ -166,7 +172,7 @@ HSH_Copy(const struct sess *sp, struct objhead *oh)
*b++ = '#'; *b++ = '#';
} }
*b++ = '\0'; *b++ = '\0';
assert(b <= oh->hash + oh->hashlen); assert(b <= oh->hash + sp->lhashptr);
} }
void void
...@@ -229,6 +235,7 @@ HSH_Lookup(struct sess *sp) ...@@ -229,6 +235,7 @@ HSH_Lookup(struct sess *sp)
{ {
struct worker *w; struct worker *w;
struct objhead *oh; struct objhead *oh;
struct objcore *oc;
struct object *o, *busy_o, *grace_o; struct object *o, *busy_o, *grace_o;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
...@@ -257,7 +264,11 @@ HSH_Lookup(struct sess *sp) ...@@ -257,7 +264,11 @@ HSH_Lookup(struct sess *sp)
busy_o = NULL; busy_o = NULL;
grace_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) { if (o->busy) {
busy_o = o; busy_o = o;
continue; continue;
...@@ -279,6 +290,10 @@ HSH_Lookup(struct sess *sp) ...@@ -279,6 +290,10 @@ HSH_Lookup(struct sess *sp)
if (o->ttl + HSH_Grace(o->grace) >= sp->t_req) if (o->ttl + HSH_Grace(o->grace) >= sp->t_req)
grace_o = o; grace_o = o;
} }
if (oc == NULL)
o = NULL;
else
AN(o);
/* /*
* If we have a object in grace and being fetched, * If we have a object in grace and being fetched,
...@@ -314,9 +329,15 @@ HSH_Lookup(struct sess *sp) ...@@ -314,9 +329,15 @@ HSH_Lookup(struct sess *sp)
/* Insert (precreated) object in objecthead */ /* Insert (precreated) object in objecthead */
o = w->nobj; o = w->nobj;
w->nobj = NULL; w->nobj = NULL;
oc = w->nobjcore;
w->nobjcore = NULL;
o->objhead = oh; o->objhead = oh;
o->objcore = oc;
oc->obj = o;
/* XXX: Should this not be ..._HEAD now ? */ /* 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 */ /* NB: do not deref objhead the new object inherits our reference */
if (grace_o != NULL) { if (grace_o != NULL) {
grace_o->child = o; grace_o->child = o;
...@@ -419,6 +440,7 @@ HSH_Deref(struct object **oo) ...@@ -419,6 +440,7 @@ HSH_Deref(struct object **oo)
{ {
struct object *o; struct object *o;
struct objhead *oh; struct objhead *oh;
struct objcore *oc;
unsigned r; unsigned r;
AN(oo); AN(oo);
...@@ -426,19 +448,22 @@ HSH_Deref(struct object **oo) ...@@ -426,19 +448,22 @@ HSH_Deref(struct object **oo)
*oo = NULL; *oo = NULL;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
oh = o->objhead; oh = o->objhead;
if (oh != NULL) { if (oh == NULL) {
oc = NULL;
assert(o->refcnt > 0);
r = --o->refcnt;
} else {
CHECK_OBJ(oh, OBJHEAD_MAGIC); CHECK_OBJ(oh, OBJHEAD_MAGIC);
/* drop ref on object */ oc = o->objcore;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
Lck_Lock(&oh->mtx); Lck_Lock(&oh->mtx);
} assert(o->refcnt > 0);
assert(o->refcnt > 0); r = --o->refcnt;
r = --o->refcnt;
if (oh != NULL)
hsh_rush(oh);
if (oh != NULL) {
if (!r) if (!r)
VTAILQ_REMOVE(&oh->objects, o, list); VTAILQ_REMOVE(&oh->objcs, oc, list);
hsh_rush(oh);
Lck_Unlock(&oh->mtx); Lck_Unlock(&oh->mtx);
} }
...@@ -458,12 +483,16 @@ HSH_Deref(struct object **oo) ...@@ -458,12 +483,16 @@ HSH_Deref(struct object **oo)
STV_free(o->objstore); STV_free(o->objstore);
VSL_stats->n_object--; VSL_stats->n_object--;
if (oh == NULL) if (oh == NULL) {
AZ(oc);
return; return;
}
AN(oc);
FREE_OBJ(oc);
/* Drop our ref on the objhead */ /* Drop our ref on the objhead */
if (hash->deref(oh)) if (hash->deref(oh))
return; return;
assert(VTAILQ_EMPTY(&oh->objects)); assert(VTAILQ_EMPTY(&oh->objcs));
Lck_Delete(&oh->mtx); Lck_Delete(&oh->mtx);
VSL_stats->n_objecthead--; VSL_stats->n_objecthead--;
free(oh->hash); free(oh->hash);
......
...@@ -432,7 +432,6 @@ hcb_lookup(const struct sess *sp, struct objhead *noh) ...@@ -432,7 +432,6 @@ hcb_lookup(const struct sess *sp, struct objhead *noh)
} else { } else {
free(noh->hash); free(noh->hash);
noh->hash = NULL; noh->hash = NULL;
noh->hashlen = 0;
VSL_stats->hcb_lock++; VSL_stats->hcb_lock++;
#ifdef PHK #ifdef PHK
fprintf(stderr, "hcb_lookup %d\n", __LINE__); fprintf(stderr, "hcb_lookup %d\n", __LINE__);
......
...@@ -73,11 +73,10 @@ struct objhead { ...@@ -73,11 +73,10 @@ struct objhead {
struct lock mtx; struct lock mtx;
unsigned refcnt; unsigned refcnt;
VTAILQ_HEAD(,object) objects; VTAILQ_HEAD(,objcore) objcs;
char *hash; char *hash;
unsigned hashlen;
unsigned char digest[DIGEST_LEN]; unsigned char digest[DIGEST_LEN];
#ifdef NOT_YET #ifndef NOT_YET
union { union {
VTAILQ_HEAD(, sess) __u_waitinglist; VTAILQ_HEAD(, sess) __u_waitinglist;
VTAILQ_ENTRY(objhead) __u_coollist; VTAILQ_ENTRY(objhead) __u_coollist;
......
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