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 {
#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;
......
......@@ -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);
}
/*--------------------------------------------------------------------*/
......
......@@ -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);
......
......@@ -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);
......
......@@ -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__);
......
......@@ -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;
......
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