r5615 - in trunk/varnish-cache: bin/varnishd include
phk at varnish-cache.org
phk at varnish-cache.org
Mon Nov 29 16:07:14 CET 2010
Author: phk
Date: 2010-11-29 16:07:14 +0100 (Mon, 29 Nov 2010)
New Revision: 5615
Modified:
trunk/varnish-cache/bin/varnishd/cache.h
trunk/varnish-cache/bin/varnishd/cache_hash.c
trunk/varnish-cache/bin/varnishd/hash_critbit.c
trunk/varnish-cache/bin/varnishd/hash_slinger.h
trunk/varnish-cache/include/vsc_fields.h
Log:
Add a proper hash-slinger method for lookup preparation, and use this
in critbit to avoid a malloc in the locked path.
Move the waitinglist to its own structure in preparation for Big
Things Afoot which will give it more work to do. This saves a
pointer in objhead on average, always a good thing.
Have the worker thread preallocate a waitinglist structure.
Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h 2010-11-29 15:04:43 UTC (rev 5614)
+++ trunk/varnish-cache/bin/varnishd/cache.h 2010-11-29 15:07:14 UTC (rev 5615)
@@ -97,6 +97,7 @@
struct ban;
struct SHA256Context;
struct vsc_lck;
+struct waitinglist;
struct lock { void *priv; }; // Opaque
@@ -216,6 +217,7 @@
#define WORKER_MAGIC 0x6391adcf
struct objhead *nobjhead;
struct objcore *nobjcore;
+ struct waitinglist *nwaitinglist;
void *nhashpriv;
struct dstat stats;
Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-11-29 15:04:43 UTC (rev 5614)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-11-29 15:07:14 UTC (rev 5615)
@@ -87,6 +87,7 @@
struct worker *w;
struct objhead *oh;
struct objcore *oc;
+ struct waitinglist *wl;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
@@ -106,12 +107,23 @@
XXXAN(oh);
oh->refcnt = 1;
VTAILQ_INIT(&oh->objcs);
- VTAILQ_INIT(&oh->waitinglist);
Lck_New(&oh->mtx, lck_objhdr);
w->nobjhead = oh;
w->stats.n_objecthead++;
}
CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC);
+
+ if (w->nwaitinglist == NULL) {
+ ALLOC_OBJ(wl, WAITINGLIST_MAGIC);
+ XXXAN(wl);
+ VTAILQ_INIT(&wl->list);
+ w->nwaitinglist = wl;
+ w->stats.n_waitinglist++;
+ }
+ CHECK_OBJ_NOTNULL(w->nwaitinglist, WAITINGLIST_MAGIC);
+
+ if (hash->prep != NULL)
+ hash->prep(sp);
}
void
@@ -129,7 +141,12 @@
w->nobjhead = NULL;
w->stats.n_objecthead--;
}
+ if (w->nwaitinglist != NULL) {
+ FREE_OBJ(w->nwaitinglist);
+ w->nwaitinglist = NULL;
+ }
if (w->nhashpriv != NULL) {
+ /* XXX: If needed, add slinger method for this */
free(w->nhashpriv);
w->nhashpriv = NULL;
}
@@ -412,8 +429,15 @@
if (busy_oc != NULL) {
/* There are one or more busy objects, wait for them */
- if (sp->esis == 0)
- VTAILQ_INSERT_TAIL(&oh->waitinglist, sp, list);
+ if (sp->esis == 0) {
+ CHECK_OBJ_NOTNULL(sp->wrk->nwaitinglist,
+ WAITINGLIST_MAGIC);
+ if (oh->waitinglist == NULL) {
+ oh->waitinglist = sp->wrk->nwaitinglist;
+ sp->wrk->nwaitinglist = NULL;
+ }
+ VTAILQ_INSERT_TAIL(&oh->waitinglist->list, sp, list);
+ }
if (params->diag_bitmap & 0x20)
WSP(sp, SLT_Debug,
"on waiting list <%p>", oh);
@@ -451,16 +475,24 @@
{
unsigned u;
struct sess *sp;
+ struct waitinglist *wl;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
Lck_AssertHeld(&oh->mtx);
+ wl = oh->waitinglist;
+ if (wl == NULL)
+ return;
+ CHECK_OBJ_NOTNULL(wl, WAITINGLIST_MAGIC);
for (u = 0; u < params->rush_exponent; u++) {
- sp = VTAILQ_FIRST(&oh->waitinglist);
- if (sp == NULL)
+ sp = VTAILQ_FIRST(&wl->list);
+ if (sp == NULL) {
+ oh->waitinglist = NULL;
+ FREE_OBJ(wl);
return;
+ }
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
AZ(sp->wrk);
- VTAILQ_REMOVE(&oh->waitinglist, sp, list);
+ VTAILQ_REMOVE(&wl->list, sp, list);
DSL(0x20, SLT_Debug, sp->id, "off waiting list");
if (WRK_QueueSession(sp)) {
/*
Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/hash_critbit.c 2010-11-29 15:04:43 UTC (rev 5614)
+++ trunk/varnish-cache/bin/varnishd/hash_critbit.c 2010-11-29 15:07:14 UTC (rev 5615)
@@ -408,7 +408,7 @@
VTAILQ_INSERT_TAIL(&cool_h, oh, hoh_list);
Lck_Unlock(&hcb_mtx);
assert(VTAILQ_EMPTY(&oh->objcs));
- assert(VTAILQ_EMPTY(&oh->waitinglist));
+ AZ(oh->waitinglist);
}
Lck_Unlock(&oh->mtx);
#ifdef PHK
@@ -430,11 +430,7 @@
with_lock = 0;
while (1) {
if (with_lock) {
- if (sp->wrk->nhashpriv == NULL) {
- ALLOC_OBJ(y, HCB_Y_MAGIC);
- sp->wrk->nhashpriv = y;
- }
- AN(sp->wrk->nhashpriv);
+ CAST_OBJ_NOTNULL(y, sp->wrk->nhashpriv, HCB_Y_MAGIC);
Lck_Lock(&hcb_mtx);
VSC_main->hcb_lock++;
assert(noh->refcnt == 1);
@@ -477,11 +473,22 @@
}
}
+static void
+hcb_prep(const struct sess *sp)
+{
+ struct hcb_y *y;
+ if (sp->wrk->nhashpriv == NULL) {
+ ALLOC_OBJ(y, HCB_Y_MAGIC);
+ sp->wrk->nhashpriv = y;
+ }
+}
+
const struct hash_slinger hcb_slinger = {
- .magic = SLINGER_MAGIC,
- .name = "critbit",
- .start = hcb_start,
- .lookup = hcb_lookup,
- .deref = hcb_deref,
+ .magic = SLINGER_MAGIC,
+ .name = "critbit",
+ .start = hcb_start,
+ .lookup = hcb_lookup,
+ .prep = hcb_prep,
+ .deref = hcb_deref,
};
Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/hash_slinger.h 2010-11-29 15:04:43 UTC (rev 5614)
+++ trunk/varnish-cache/bin/varnishd/hash_slinger.h 2010-11-29 15:07:14 UTC (rev 5615)
@@ -35,6 +35,7 @@
typedef void hash_init_f(int ac, char * const *av);
typedef void hash_start_f(void);
+typedef void hash_prep_f(const struct sess *sp);
typedef struct objhead *
hash_lookup_f(const struct sess *sp, struct objhead *nobj);
typedef int hash_deref_f(struct objhead *obj);
@@ -45,6 +46,7 @@
const char *name;
hash_init_f *init;
hash_start_f *start;
+ hash_prep_f *prep;
hash_lookup_f *lookup;
hash_deref_f *deref;
};
@@ -66,6 +68,12 @@
#ifdef VARNISH_CACHE_CHILD
+struct waitinglist {
+ unsigned magic;
+#define WAITINGLIST_MAGIC 0x063a477a
+ VTAILQ_HEAD(, sess) list;
+};
+
struct objhead {
unsigned magic;
#define OBJHEAD_MAGIC 0x1b96615d
@@ -74,7 +82,7 @@
int refcnt;
VTAILQ_HEAD(,objcore) objcs;
unsigned char digest[DIGEST_LEN];
- VTAILQ_HEAD(, sess) waitinglist;
+ struct waitinglist *waitinglist;
/*----------------------------------------------------
* The fields below are for the sole private use of
Modified: trunk/varnish-cache/include/vsc_fields.h
===================================================================
--- trunk/varnish-cache/include/vsc_fields.h 2010-11-29 15:04:43 UTC (rev 5614)
+++ trunk/varnish-cache/include/vsc_fields.h 2010-11-29 15:07:14 UTC (rev 5615)
@@ -70,11 +70,12 @@
VSC_F(n_sess_mem, uint64_t, 0, 'i', "N struct sess_mem")
-VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess")
-VSC_F(n_object, uint64_t, 1, 'i', "N struct object")
-VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects")
-VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore")
-VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead")
+VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess")
+VSC_F(n_object, uint64_t, 1, 'i', "N struct object")
+VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects")
+VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore")
+VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead")
+VSC_F(n_waitinglist, uint64_t, 1, 'i', "N struct waitinglist")
VSC_F(n_vbc, uint64_t, 0, 'i', "N struct vbc")
VSC_F(n_wrk, uint64_t, 0, 'i', "N worker threads")
More information about the varnish-commit
mailing list