r510 - in trunk/varnish-cache: bin/varnishd include
phk at projects.linpro.no
phk at projects.linpro.no
Wed Jul 19 23:16:03 CEST 2006
Author: phk
Date: 2006-07-19 23:16:03 +0200 (Wed, 19 Jul 2006)
New Revision: 510
Modified:
trunk/varnish-cache/bin/varnishd/cache_pool.c
trunk/varnish-cache/include/stat_field.h
Log:
Rework the worker thread pool logic slightly, we were leaking
threads before.
Modified: trunk/varnish-cache/bin/varnishd/cache_pool.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pool.c 2006-07-19 21:14:41 UTC (rev 509)
+++ trunk/varnish-cache/bin/varnishd/cache_pool.c 2006-07-19 21:16:03 UTC (rev 510)
@@ -26,11 +26,37 @@
/*--------------------------------------------------------------------*/
+static void
+wrk_do_one(struct worker *w)
+{
+ struct workreq *wrq;
+
+ wrq = TAILQ_FIRST(&wrk_reqhead);
+ assert(wrq != NULL);
+ VSL_stats->n_wrk_busy++;
+ TAILQ_REMOVE(&wrk_reqhead, wrq, list);
+ VSL_stats->n_wrk_queue--;
+ AZ(pthread_mutex_unlock(&wrk_mtx));
+ assert(wrq->sess != NULL);
+ wrq->sess->wrk = w;
+ CHECK_OBJ_NOTNULL(wrq->sess, SESS_MAGIC);
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
+ CNT_Session(wrq->sess);
+ if (w->nobj != NULL)
+ CHECK_OBJ(w->nobj, OBJECT_MAGIC);
+ if (w->nobjhead != NULL)
+ CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
+ AZ(pthread_mutex_lock(&wrk_mtx));
+ VSL_stats->n_wrk_busy--;
+}
+
static void *
wrk_thread(void *priv)
{
struct worker *w, ww;
- struct workreq *wrq;
struct timespec ts;
w = &ww;
@@ -50,66 +76,40 @@
if (priv == NULL) {
VSL_stats->n_wrk_create++;
VSL(SLT_WorkThread, 0, "%u born dynamic", w->nbr);
- } else {
- VSL(SLT_WorkThread, 0, "%u born permanent", w->nbr);
}
- TAILQ_INSERT_HEAD(&wrk_head, w, list);
while (1) {
CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
- if (w->nobj != NULL)
- CHECK_OBJ(w->nobj, OBJECT_MAGIC);
- if (w->nobjhead != NULL)
- CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
- wrq = TAILQ_FIRST(&wrk_reqhead);
- if (wrq != NULL) {
- VSL_stats->n_wrk_busy++;
- TAILQ_REMOVE(&wrk_head, w, list);
- TAILQ_REMOVE(&wrk_reqhead, wrq, list);
- AZ(pthread_mutex_unlock(&wrk_mtx));
- assert(wrq->sess != NULL);
- wrq->sess->wrk = w;
- CHECK_OBJ_NOTNULL(wrq->sess, SESS_MAGIC);
- CNT_Session(wrq->sess);
- AZ(pthread_mutex_lock(&wrk_mtx));
- VSL_stats->n_wrk_busy--;
- TAILQ_INSERT_HEAD(&wrk_head, w, list);
- }
+
+ /* Process overflow requests, if any */
if (wrk_overflow > 0) {
wrk_overflow--;
+ wrk_do_one(w);
continue;
}
- if (w->nobj != NULL)
- CHECK_OBJ(w->nobj, OBJECT_MAGIC);
- if (w->nobjhead != NULL)
- CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
+
+ TAILQ_INSERT_HEAD(&wrk_head, w, list);
/* If we are a reserved thread we don't die */
if (priv != NULL) {
AZ(pthread_cond_wait(&w->cv, &wrk_mtx));
- continue;
+ } else {
+ /* If we are a dynamic thread, time out and die */
+ AZ(clock_gettime(CLOCK_REALTIME, &ts));
+ ts.tv_sec += heritage.wthread_timeout;
+ if (pthread_cond_timedwait(&w->cv, &wrk_mtx, &ts)) {
+ VSL_stats->n_wrk--;
+ TAILQ_REMOVE(&wrk_head, w, list);
+ AZ(pthread_mutex_unlock(&wrk_mtx));
+ VSL(SLT_WorkThread, 0, "%u suicide", w->nbr);
+ sbuf_delete(w->sb);
+ event_base_free(w->eb);
+ AZ(pthread_cond_destroy(&w->cv));
+ return (NULL);
+ }
}
- if (w->nobj != NULL)
- CHECK_OBJ(w->nobj, OBJECT_MAGIC);
- if (w->nobjhead != NULL)
- CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
- /* If we are a dynamic thread, time out and die */
- AZ(clock_gettime(CLOCK_REALTIME, &ts));
- ts.tv_sec += heritage.wthread_timeout;
- if (pthread_cond_timedwait(&w->cv, &wrk_mtx, &ts)) {
- VSL_stats->n_wrk--;
- TAILQ_REMOVE(&wrk_head, w, list);
- AZ(pthread_mutex_unlock(&wrk_mtx));
- VSL(SLT_WorkThread, 0, "%u suicide", w->nbr);
- sbuf_delete(w->sb);
- event_base_free(w->eb);
- AZ(pthread_cond_destroy(&w->cv));
- return (NULL);
- }
- if (w->nobj != NULL)
- CHECK_OBJ(w->nobj, OBJECT_MAGIC);
- if (w->nobjhead != NULL)
- CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC);
+ /* we are already removed from wrk_head */
+ wrk_do_one(w);
}
}
@@ -127,19 +127,22 @@
AZ(pthread_mutex_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_head);
if (w != NULL) {
AZ(pthread_cond_signal(&w->cv));
+ TAILQ_REMOVE(&wrk_head, w, list);
AZ(pthread_mutex_unlock(&wrk_mtx));
return;
}
- /* Register overflow if max threads reached */
+ wrk_overflow++;
+
+ /* Can we create more threads ? */
if (VSL_stats->n_wrk >= heritage.wthread_max) {
- wrk_overflow++;
- VSL_stats->n_wrk_short++;
+ VSL_stats->n_wrk_max++;
AZ(pthread_mutex_unlock(&wrk_mtx));
return;
}
@@ -147,6 +150,7 @@
/* Try to create a thread */
VSL_stats->n_wrk++;
AZ(pthread_mutex_unlock(&wrk_mtx));
+
if (!pthread_create(&tp, NULL, wrk_thread, NULL)) {
AZ(pthread_detach(tp));
return;
@@ -158,9 +162,7 @@
/* Register overflow */
AZ(pthread_mutex_lock(&wrk_mtx));
VSL_stats->n_wrk--;
- wrk_overflow++;
VSL_stats->n_wrk_failed++;
- VSL_stats->n_wrk_short++;
AZ(pthread_mutex_unlock(&wrk_mtx));
}
Modified: trunk/varnish-cache/include/stat_field.h
===================================================================
--- trunk/varnish-cache/include/stat_field.h 2006-07-19 21:14:41 UTC (rev 509)
+++ trunk/varnish-cache/include/stat_field.h 2006-07-19 21:16:03 UTC (rev 510)
@@ -21,7 +21,8 @@
MAC_STAT(n_wrk, uint64_t, "u", "N worker threads")
MAC_STAT(n_wrk_create, uint64_t, "u", "N worker threads created")
MAC_STAT(n_wrk_failed, uint64_t, "u", "N worker threads not created")
-MAC_STAT(n_wrk_short, uint64_t, "u", "N worker threads shortages")
+MAC_STAT(n_wrk_max, uint64_t, "u", "N worker threads limited")
MAC_STAT(n_wrk_busy, uint64_t, "u", "N busy worker threads")
+MAC_STAT(n_wrk_queue, uint64_t, "u", "N queued work requests")
MAC_STAT(losthdr, uint64_t, "u", "HTTP header overflows")
More information about the varnish-commit
mailing list