[master] c522f7a Record the start and end of the worker thread stack.

Poul-Henning Kamp phk at FreeBSD.org
Mon Sep 22 11:44:24 CEST 2014


commit c522f7af7abaf8d847d62f8edaa46a2f5c0178e3
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Sep 22 09:44:03 2014 +0000

    Record the start and end of the worker thread stack.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b4e79c4..289ea28 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -367,6 +367,9 @@ struct worker {
 	unsigned		cur_method;
 	unsigned		seen_methods;
 	unsigned		handling;
+
+	uintptr_t		stack_start;
+	uintptr_t		stack_end;
 };
 
 /* LRU ---------------------------------------------------------------*/
@@ -1020,7 +1023,7 @@ void PipeRequest(struct req *req, struct busyobj *bo);
 /* cache_pool.c */
 void Pool_Init(void);
 void Pool_Accept(void);
-void Pool_Work_Thread(void *priv, struct worker *w);
+void Pool_Work_Thread(struct pool *, struct worker *w);
 int Pool_Task(struct pool *pp, struct pool_task *task, enum pool_how how);
 void Pool_Sumstat(struct worker *w);
 void Pool_PurgeStat(unsigned nobj);
@@ -1136,7 +1139,7 @@ void WAIT_Write_Session(struct sess *sp, int fd);
 
 /* cache_wrk.c */
 
-void *WRK_thread(void *priv);
+void WRK_Thread(struct pool *qp, size_t stacksize, unsigned thread_workspace);
 typedef void *bgthread_t(struct worker *, void *priv);
 void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func,
     void *priv);
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index c666d8a..625f314 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -277,6 +277,8 @@ pan_wrk(const struct worker *wrk)
 	const char *p;
 
 	VSB_printf(pan_vsp, "  worker = %p {\n", wrk);
+	VSB_printf(pan_vsp, "    stack = {0x%jx -> 0x%jx}\n",
+	    wrk->stack_start, wrk->stack_end);
 	pan_ws(wrk->aws, 4);
 
 	m = wrk->cur_method;
diff --git a/bin/varnishd/cache/cache_pool.c b/bin/varnishd/cache/cache_pool.c
index 77524b3..916c4a3 100644
--- a/bin/varnishd/cache/cache_pool.c
+++ b/bin/varnishd/cache/cache_pool.c
@@ -348,14 +348,13 @@ pool_stat_summ(struct worker *wrk, void *priv)
  */
 
 void
-Pool_Work_Thread(void *priv, struct worker *wrk)
+Pool_Work_Thread(struct pool *pp, struct worker *wrk)
 {
-	struct pool *pp;
 	struct pool_task *tp;
 	struct pool_task tps;
 	int i;
 
-	CAST_OBJ_NOTNULL(pp, priv, POOL_MAGIC);
+	CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);
 	wrk->pool = pp;
 	while (1) {
 		Lck_Lock(&pp->mtx);
@@ -416,15 +415,48 @@ Pool_Work_Thread(void *priv, struct worker *wrk)
 }
 
 /*--------------------------------------------------------------------
- * Create another thread.
+ * Create another worker thread.
  */
 
+struct pool_info {
+	unsigned		magic;
+#define POOL_INFO_MAGIC		0x4e4442d3
+	size_t			stacksize;
+	struct pool		*qp;
+};
+
+static void *
+pool_thread(void *priv)
+{
+	struct pool_info *pi;
+
+	CAST_OBJ_NOTNULL(pi, priv, POOL_INFO_MAGIC);
+	WRK_Thread(pi->qp, pi->stacksize, cache_param->workspace_thread);
+	FREE_OBJ(pi);
+	return (NULL);
+}
+
 static void
-pool_breed(struct pool *qp, const pthread_attr_t *tp_attr)
+pool_breed(struct pool *qp)
 {
 	pthread_t tp;
+	pthread_attr_t tp_attr;
+	struct pool_info *pi;
+
+	AZ(pthread_attr_init(&tp_attr));
+	AZ(pthread_attr_setdetachstate(&tp_attr, PTHREAD_CREATE_DETACHED));
+
+	/* Set the stacksize for worker threads we create */
+	if (cache_param->wthread_stacksize != UINT_MAX)
+		AZ(pthread_attr_setstacksize(&tp_attr,
+		    cache_param->wthread_stacksize));
+
+	ALLOC_OBJ(pi, POOL_INFO_MAGIC);
+	AN(pi);
+	AZ(pthread_attr_getstacksize(&tp_attr, &pi->stacksize));
+	pi->qp = qp;
 
-	if (pthread_create(&tp, tp_attr, WRK_thread, qp)) {
+	if (pthread_create(&tp, &tp_attr, pool_thread, pi)) {
 		VSL(SLT_Debug, 0, "Create worker thread failed %d %s",
 		    errno, strerror(errno));
 		Lck_Lock(&pool_mtx);
@@ -432,7 +464,6 @@ pool_breed(struct pool *qp, const pthread_attr_t *tp_attr)
 		Lck_Unlock(&pool_mtx);
 		VTIM_sleep(cache_param->wthread_fail_delay);
 	} else {
-		AZ(pthread_detach(tp));
 		qp->dry = 0;
 		qp->nthr++;
 		Lck_Lock(&pool_mtx);
@@ -441,6 +472,8 @@ pool_breed(struct pool *qp, const pthread_attr_t *tp_attr)
 		Lck_Unlock(&pool_mtx);
 		VTIM_sleep(cache_param->wthread_add_delay);
 	}
+
+	AZ(pthread_attr_destroy(&tp_attr));
 }
 
 /*--------------------------------------------------------------------
@@ -463,27 +496,16 @@ pool_herder(void *priv)
 {
 	struct pool *pp;
 	struct pool_task *pt;
-	pthread_attr_t tp_attr;
 	double t_idle;
 	struct worker *wrk;
 
 	CAST_OBJ_NOTNULL(pp, priv, POOL_MAGIC);
-	AZ(pthread_attr_init(&tp_attr));
 
 	while (1) {
-		/* Set the stacksize for worker threads we create */
-		if (cache_param->wthread_stacksize != UINT_MAX)
-			AZ(pthread_attr_setstacksize(&tp_attr,
-			    cache_param->wthread_stacksize));
-		else {
-			AZ(pthread_attr_destroy(&tp_attr));
-			AZ(pthread_attr_init(&tp_attr));
-		}
-
 		/* Make more threads if needed and allowed */
 		if (pp->nthr < cache_param->wthread_min ||
 		    (pp->dry && pp->nthr < cache_param->wthread_max)) {
-			pool_breed(pp, &tp_attr);
+			pool_breed(pp);
 			continue;
 		}
 
diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c
index 38a662b..26930ff 100644
--- a/bin/varnishd/cache/cache_wrk.c
+++ b/bin/varnishd/cache/cache_wrk.c
@@ -32,6 +32,7 @@
 #include "config.h"
 
 #include <math.h>
+#include <unistd.h>
 #include <stdlib.h>
 
 #include "cache.h"
@@ -84,11 +85,16 @@ WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func, void *priv)
 
 /*--------------------------------------------------------------------*/
 
-static void *
-wrk_thread_real(void *priv, unsigned thread_workspace)
+void
+WRK_Thread(struct pool *qp, size_t stacksize, unsigned thread_workspace)
 {
 	struct worker *w, ww;
 	unsigned char ws[thread_workspace];
+	uintptr_t u;
+
+	AN(qp);
+	AN(stacksize);
+	AN(thread_workspace);
 
 	THR_SetName("cache-worker");
 	w = &ww;
@@ -99,9 +105,17 @@ wrk_thread_real(void *priv, unsigned thread_workspace)
 
 	WS_Init(w->aws, "wrk", ws, thread_workspace);
 
+	u = getpagesize();
+	AN(u);
+	u -= 1U;
+	w->stack_start = (((uintptr_t)&qp) + u) & ~u;
+
+	/* XXX: assuming stack grows down. */
+	w->stack_end = w->stack_start - stacksize;
+
 	VSL(SLT_WorkThread, 0, "%p start", w);
 
-	Pool_Work_Thread(priv, w);
+	Pool_Work_Thread(qp, w);
 	AZ(w->pool);
 
 	VSL(SLT_WorkThread, 0, "%p end", w);
@@ -112,12 +126,4 @@ wrk_thread_real(void *priv, unsigned thread_workspace)
 		VBO_Free(&w->nbo);
 	HSH_Cleanup(w);
 	Pool_Sumstat(w);
-	return (NULL);
-}
-
-void *
-WRK_thread(void *priv)
-{
-
-	return (wrk_thread_real(priv, cache_param->workspace_thread));
 }



More information about the varnish-commit mailing list