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