[master] 159c511 Further mempool-polishing:

Poul-Henning Kamp phk at varnish-cache.org
Thu Dec 22 20:29:12 CET 2011


commit 159c511d774bed9cc1b6774941640a75b4418931
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Dec 22 19:26:46 2011 +0000

    Further mempool-polishing:
    
    Drop the mtx arg to MPL_New(), it wouldn't help.
    
    Store the pool name locally.
    
    Fix wrong type on some stats counters.
    
    Copy gauge counters from reliable values.
    
    Add stats-counter for dry pool allocations.
    
    Add MPL_Destroy() which tickles the guard thread into self-destroying
    the pool.  Only allowed if no live objects.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 46a0d26..d3b34b7 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -871,8 +871,9 @@ int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts);
 #undef LOCK
 
 /* cache_mempool.c */
-struct mempool * MPL_New(const char *name, struct lock *mtx,
-    volatile struct poolparam *pp, volatile unsigned *cur_size);
+struct mempool * MPL_New(const char *name, volatile struct poolparam *pp,
+    volatile unsigned *cur_size);
+void MPL_Destroy(struct mempool **mpp);
 void *MPL_Get(struct mempool *mpl, unsigned *size);
 void MPL_Free(struct mempool *mpl, void *item);
 
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 6cfcaf3..48c01a3 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -518,6 +518,6 @@ void
 VDI_Init(void)
 {
 
-	vbcpool = MPL_New("vbc", NULL, &cache_param->vbc_pool, &vbcps);
+	vbcpool = MPL_New("vbc", &cache_param->vbc_pool, &vbcps);
 	AN(vbcpool);
 }
diff --git a/bin/varnishd/cache/cache_mempool.c b/bin/varnishd/cache/cache_mempool.c
index 92e38d2..a89f1e7 100644
--- a/bin/varnishd/cache/cache_mempool.c
+++ b/bin/varnishd/cache/cache_mempool.c
@@ -51,17 +51,18 @@ VTAILQ_HEAD(memhead_s, memitem);
 struct mempool {
 	unsigned			magic;
 #define MEMPOOL_MAGIC			0x37a75a8d
+	char				name[8];
 	struct memhead_s		list;
 	struct memhead_s		surplus;
-	struct lock			*mtx;
-	struct lock			imtx;
-	const char			*name;
+	struct lock			mtx;
 	volatile struct poolparam	*param;
 	volatile unsigned		*cur_size;
+	uint64_t			live;
 	struct VSC_C_mempool		*vsc;
 	unsigned			n_pool;
 	pthread_t			thread;
 	double				t_now;
+	int				self_destruct;
 };
 
 /*---------------------------------------------------------------------
@@ -124,20 +125,50 @@ mpl_guard(void *priv)
 			/* can do */
 		} else if (last + .1 * mpl->param->max_age < mpl->t_now) {
 			/* should do */
+		} else if (mpl->self_destruct) {
+			/* can do */
 		} else {
 			continue;	/* nothing to do */
 		}
 
 		mpl_slp = 0.314;	// random
 
-		if (Lck_Trylock(mpl->mtx))
+		if (Lck_Trylock(&mpl->mtx))
 			continue;
 
+		if (mpl->self_destruct) {
+			AZ(mpl->live);
+			while (1) {
+				if (mi == NULL) {
+					mi = VTAILQ_FIRST(&mpl->list);
+					if (mi != NULL) {
+						mpl->vsc->pool = --mpl->n_pool;
+						VTAILQ_REMOVE(&mpl->list,
+						    mi, list);
+					}
+				}
+				if (mi == NULL) {
+					mi = VTAILQ_FIRST(&mpl->surplus);
+					if (mi != NULL)
+						VTAILQ_REMOVE(&mpl->surplus,
+						    mi, list);
+				}
+				if (mi == NULL) 
+					break;
+				FREE_OBJ(mi);
+				mi = NULL;
+			}
+			VSM_Free(mpl->vsc);
+			Lck_Unlock(&mpl->mtx);
+			Lck_Delete(&mpl->mtx);
+			FREE_OBJ(mpl);
+			break;
+		}
+
 		if (mpl->n_pool < mpl->param->min_pool &&
 		    mi != NULL && mi->size >= *mpl->cur_size) {
 			CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
-			mpl->vsc->pool++;
-			mpl->n_pool++;
+			mpl->vsc->pool = ++mpl->n_pool;
 			mi->touched = mpl->t_now;
 			VTAILQ_INSERT_HEAD(&mpl->list, mi, list);
 			mi = NULL;
@@ -147,9 +178,8 @@ mpl_guard(void *priv)
 		if (mpl->n_pool > mpl->param->max_pool && mi == NULL) {
 			mi = VTAILQ_FIRST(&mpl->list);
 			CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
-			mpl->vsc->pool--;
+			mpl->vsc->pool = --mpl->n_pool;
 			mpl->vsc->surplus++;
-			mpl->n_pool--;
 			VTAILQ_REMOVE(&mpl->list, mi, list);
 			mpl_slp = .01;	// random
 		}
@@ -165,9 +195,8 @@ mpl_guard(void *priv)
 			mi = VTAILQ_LAST(&mpl->list, memhead_s);
 			CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
 			if (mi->touched + mpl->param->max_age < mpl->t_now) {
-				mpl->vsc->pool--;
+				mpl->vsc->pool = --mpl->n_pool;
 				mpl->vsc->timeout++;
-				mpl->n_pool--;
 				VTAILQ_REMOVE(&mpl->list, mi, list);
 				mpl_slp = .01;	// random
 			} else {
@@ -178,22 +207,22 @@ mpl_guard(void *priv)
 			last = mpl->t_now;
 		}
 
-		Lck_Unlock(mpl->mtx);
+		Lck_Unlock(&mpl->mtx);
 
 		if (mi != NULL) {
 			FREE_OBJ(mi);
 			mi = NULL;
 		}
 	}
-	NEEDLESS_RETURN(NULL);
+	return (NULL);
 }
 
 /*---------------------------------------------------------------------
+ * Create a new memory pool, and start the guard thread for it.
  */
 
 struct mempool *
 MPL_New(const char *name,
-	struct lock *mtx,
 	volatile struct poolparam *pp,
 	volatile unsigned *cur_size)
 {
@@ -201,23 +230,44 @@ MPL_New(const char *name,
 
 	ALLOC_OBJ(mpl, MEMPOOL_MAGIC);
 	AN(mpl);
-	mpl->name = name;
+	bprintf(mpl->name, "%s", name);
 	mpl->param = pp;
 	mpl->cur_size = cur_size;
-	mpl->mtx = mtx;
 	VTAILQ_INIT(&mpl->list);
 	VTAILQ_INIT(&mpl->surplus);
-	Lck_New(&mpl->imtx, lck_mempool);
-	if (mpl->mtx == NULL)
-		mpl->mtx = &mpl->imtx;
+	Lck_New(&mpl->mtx, lck_mempool);
 	/* XXX: prealloc min_pool */
 	mpl->vsc = VSM_Alloc(sizeof *mpl->vsc,
-	    VSC_CLASS, VSC_TYPE_MEMPOOL, name);
+	    VSC_CLASS, VSC_TYPE_MEMPOOL, mpl->name);
 	AN(mpl->vsc);
 	AZ(pthread_create(&mpl->thread, NULL, mpl_guard, mpl));
+	AZ(pthread_detach(mpl->thread));
 	return (mpl);
 }
 
+/*---------------------------------------------------------------------
+ * Destroy a memory pool.  There must be no live items, and we cheat
+ * and leave all the hard work to the guard thread.
+ */
+
+void
+MPL_Destroy(struct mempool **mpp)
+{
+	struct mempool *mpl;
+
+	AN(mpp);
+	mpl = *mpp;
+	*mpp = NULL;
+	CHECK_OBJ_NOTNULL(mpl, MEMPOOL_MAGIC);
+	Lck_Lock(&mpl->mtx);
+	AZ(mpl->live);
+	mpl->self_destruct = 1;
+	Lck_Unlock(&mpl->mtx);
+}
+
+/*---------------------------------------------------------------------
+ */
+
 void *
 MPL_Get(struct mempool *mpl, unsigned *size)
 {
@@ -225,17 +275,18 @@ MPL_Get(struct mempool *mpl, unsigned *size)
 
 	CHECK_OBJ_NOTNULL(mpl, MEMPOOL_MAGIC);
 
-	Lck_Lock(mpl->mtx);
+	Lck_Lock(&mpl->mtx);
 
 	mpl->vsc->allocs++;
-	mpl->vsc->live++;
+	mpl->vsc->live = ++mpl->live;
 
 	do {
 		mi = VTAILQ_FIRST(&mpl->list);
-		if (mi == NULL)
+		if (mi == NULL) {
+			mpl->vsc->randry++;
 			break;
-		mpl->vsc->pool--;
-		mpl->n_pool--;
+		}
+		mpl->vsc->pool = --mpl->n_pool;
 		CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
 		VTAILQ_REMOVE(&mpl->list, mi, list);
 		if (mi->size < *mpl->cur_size) {
@@ -247,7 +298,7 @@ MPL_Get(struct mempool *mpl, unsigned *size)
 		}
 	} while (mi == NULL);
 
-	Lck_Unlock(mpl->mtx);
+	Lck_Unlock(&mpl->mtx);
 
 	if (mi == NULL)
 		mi = mpl_alloc(mpl);
@@ -269,10 +320,10 @@ MPL_Free(struct mempool *mpl, void *item)
 	CHECK_OBJ_NOTNULL(mi, MEMITEM_MAGIC);
 	memset(item, 0, mi->size);
 
-	Lck_Lock(mpl->mtx);
+	Lck_Lock(&mpl->mtx);
 
 	mpl->vsc->frees++;
-	mpl->vsc->live--;
+	mpl->vsc->live = --mpl->live;
 
 	if (mi->size < *mpl->cur_size) {
 		mpl->vsc->toosmall++;
@@ -281,11 +332,10 @@ MPL_Free(struct mempool *mpl, void *item)
 		mpl->vsc->surplus++;
 		VTAILQ_INSERT_HEAD(&mpl->surplus, mi, list);
 	} else {
-		mpl->vsc->pool++;
-		mpl->n_pool++;
+		mpl->vsc->pool = ++mpl->n_pool;
 		mi->touched = mpl->t_now;
 		VTAILQ_INSERT_HEAD(&mpl->list, mi, list);
 	}
 
-	Lck_Unlock(mpl->mtx);
+	Lck_Unlock(&mpl->mtx);
 }
diff --git a/include/tbl/vsc_fields.h b/include/tbl/vsc_fields.h
index 2671558..3d1e30a 100644
--- a/include/tbl/vsc_fields.h
+++ b/include/tbl/vsc_fields.h
@@ -109,13 +109,14 @@ VSC_F(happy,		uint64_t, 0, 'b', "Happy health probes", "")
 /**********************************************************************/
 #ifdef VSC_DO_MEMPOOL
 
-VSC_F(allocs,			uint64_t, 0, 'c', "Allocations", "")
-VSC_F(frees,			uint64_t, 0, 'c', "Frees", "")
 VSC_F(live,			uint64_t, 0, 'g', "In use", "")
 VSC_F(pool,			uint64_t, 0, 'g', "In Pool", "")
-VSC_F(recycle,			uint64_t, 0, 'g', "Recycled from pool", "")
-VSC_F(timeout,			uint64_t, 0, 'g', "Timed out from pool", "")
-VSC_F(toosmall,			uint64_t, 0, 'g', "Too small to recycle", "")
-VSC_F(surplus,			uint64_t, 0, 'g', "Too many for pool", "")
+VSC_F(allocs,			uint64_t, 0, 'c', "Allocations", "")
+VSC_F(frees,			uint64_t, 0, 'c', "Frees", "")
+VSC_F(recycle,			uint64_t, 0, 'c', "Recycled from pool", "")
+VSC_F(timeout,			uint64_t, 0, 'c', "Timed out from pool", "")
+VSC_F(toosmall,			uint64_t, 0, 'c', "Too small to recycle", "")
+VSC_F(surplus,			uint64_t, 0, 'c', "Too many for pool", "")
+VSC_F(randry,			uint64_t, 0, 'c', "Pool ran dry", "")
 
 #endif



More information about the varnish-commit mailing list