#define WORKER_MAGIC 0x6391adcf
struct objhead *nobjhead;
struct object *nobj;
+ struct objcore *nobjcore;
double lastused;
const char *timer_what;
unsigned timer_idx;
VTAILQ_ENTRY(objcore) list;
+ VTAILQ_ENTRY(objcore) lru_list;
int on_lru;
double lru_stamp;
};
double last_modified;
struct http http[1];
- VTAILQ_ENTRY(object) list;
VTAILQ_HEAD(, storage) store;
SZOF(struct sess);
SZOF(struct vbe_conn);
SZOF(struct varnish_stats);
+ SZOF(struct lock);
}
/*--------------------------------------------------------------------*/
*/
#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 ?
*/
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));
(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);
}
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++;
}
"%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);
}
}
* 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;
* 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);
if (sp->handling == VCL_RET_DISCARD) {
WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid);
- del_objcore(o);
HSH_Deref(&o);
return (1);
}
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);
{
struct worker *w;
struct objhead *oh;
+ struct objcore *oc;
struct object *o;
struct storage *st;
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);
w->nobj = o;
VSL_stats->n_object++;
- } else
- CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
+ }
+ CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
}
void
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]);
*b++ = '#';
}
*b++ = '\0';
- assert(b <= oh->hash + oh->hashlen);
+ assert(b <= oh->hash + sp->lhashptr);
}
void
{
struct worker *w;
struct objhead *oh;
+ struct objcore *oc;
struct object *o, *busy_o, *grace_o;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
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;
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,
/* 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;
{
struct object *o;
struct objhead *oh;
+ struct objcore *oc;
unsigned r;
AN(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);
}
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);
} else {
free(noh->hash);
noh->hash = NULL;
- noh->hashlen = 0;
VSL_stats->hcb_lock++;
#ifdef PHK
fprintf(stderr, "hcb_lookup %d\n", __LINE__);
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;