r965 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Mon Sep 11 16:34:48 CEST 2006


Author: phk
Date: 2006-09-11 16:34:48 +0200 (Mon, 11 Sep 2006)
New Revision: 965

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_pool.c
Log:
Redo the worker thread pool locking a bit, all the while cursing
pthreads deficient API design for it's shortcomings.


Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2006-09-11 12:00:50 UTC (rev 964)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2006-09-11 14:34:48 UTC (rev 965)
@@ -102,6 +102,8 @@
 	time_t			idle;
 
 	pthread_cond_t		cv;
+	pthread_mutex_t		mtx;
+
 	TAILQ_ENTRY(worker)	list;
 	struct workreq		*wrq;
 

Modified: trunk/varnish-cache/bin/varnishd/cache_pool.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pool.c	2006-09-11 12:00:50 UTC (rev 964)
+++ trunk/varnish-cache/bin/varnishd/cache_pool.c	2006-09-11 14:34:48 UTC (rev 965)
@@ -129,15 +129,10 @@
 {
 	struct workreq *wrq;
 
-	wrq = TAILQ_FIRST(&wrk_reqhead);
-	AN(wrq);
-	VSL_stats->n_wrk_busy++;
-	TAILQ_REMOVE(&wrk_reqhead, wrq, list);
-	VSL_stats->n_wrk_queue--;
-	UNLOCK(&wrk_mtx);
+	AN(w->wrq);
+	wrq = w->wrq;
 	CHECK_OBJ_NOTNULL(wrq->sess, SESS_MAGIC);
 	wrq->sess->wrk = w;
-	w->wrq = wrq;
 	if (w->nobj != NULL)
 		CHECK_OBJ(w->nobj, OBJECT_MAGIC);
 	if (w->nobjhead != NULL)
@@ -148,8 +143,6 @@
 	if (w->nobjhead != NULL)
 		CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
 	w->wrq = NULL;
-	LOCK(&wrk_mtx);
-	VSL_stats->n_wrk_busy--;
 }
 
 static void *
@@ -163,29 +156,42 @@
 	w->magic = WORKER_MAGIC;
 	w->idle = time(NULL);
 	AZ(pthread_cond_init(&w->cv, NULL));
+	AZ(pthread_mutex_init(&w->mtx, NULL));
 
 	VSL(SLT_WorkThread, 0, "%p start", w);
 	LOCK(&wrk_mtx);
 	VSL_stats->n_wrk_create++;
 	TAILQ_INSERT_HEAD(&wrk_busy, w, list);
+	VSL_stats->n_wrk_busy++;
 	while (1) {
 		CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
 
 		/* Process overflow requests, if any */
 		if (wrk_overflow > 0) {
 			wrk_overflow--;
+			w->wrq = TAILQ_FIRST(&wrk_reqhead);
+			TAILQ_REMOVE(&wrk_reqhead, w->wrq, list);
+			VSL_stats->n_wrk_queue--;
+			UNLOCK(&wrk_mtx);
 			wrk_do_one(w);
+			LOCK(&wrk_mtx);
 			continue;
 		}
 		
 		TAILQ_REMOVE(&wrk_busy, w, list);
 		TAILQ_INSERT_HEAD(&wrk_idle, w, list);
 		assert(w->idle != 0);
-		AZ(pthread_cond_wait(&w->cv, &wrk_mtx));
+		VSL_stats->n_wrk_busy--;
+		UNLOCK(&wrk_mtx);
+		LOCK(&w->mtx);
+		AZ(pthread_cond_wait(&w->cv, &w->mtx));
+		UNLOCK(&w->mtx);
 		if (w->idle == 0)
 			break;
 		wrk_do_one(w);
+		LOCK(&wrk_mtx);
 	}
+	LOCK(&wrk_mtx);
 	VSL_stats->n_wrk--;
 	UNLOCK(&wrk_mtx);
 	VSL(SLT_WorkThread, 0, "%p end", w);
@@ -204,19 +210,21 @@
 	sp->workreq.sess = sp;
 
 	LOCK(&wrk_mtx);
-	TAILQ_INSERT_TAIL(&wrk_reqhead, &sp->workreq, list);
-	VSL_stats->n_wrk_queue++;
 
 	/* If there are idle threads, we tickle the first one into action */
 	w = TAILQ_FIRST(&wrk_idle);
 	if (w != NULL) {
 		TAILQ_REMOVE(&wrk_idle, w, list);
 		TAILQ_INSERT_TAIL(&wrk_busy, w, list);
+		VSL_stats->n_wrk_busy++;
 		UNLOCK(&wrk_mtx);
+		w->wrq = &sp->workreq;
 		AZ(pthread_cond_signal(&w->cv));
 		return;
 	}
 	
+	TAILQ_INSERT_TAIL(&wrk_reqhead, &sp->workreq, list);
+	VSL_stats->n_wrk_queue++;
 	wrk_overflow++;
 
 	/* Can we create more threads ? */




More information about the varnish-commit mailing list