]> err.no Git - varnish/commitdiff
Add a delta-stats structure to worker threads and keep
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 20 Feb 2009 15:25:06 +0000 (15:25 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 20 Feb 2009 15:25:06 +0000 (15:25 +0000)
track of n_object and n_objecthead in them.

Accumulate into global stats after work is done if the lock is
free and always before going idle.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3796 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_expire.c
varnish-cache/bin/varnishd/cache_hash.c
varnish-cache/bin/varnishd/cache_pool.c
varnish-cache/bin/varnishd/hash_critbit.c
varnish-cache/bin/varnishd/hash_slinger.h
varnish-cache/include/stat_field.h

index 5345988bb39b7b6d99c121b729be5c651bd24907..af1a29450660da90d95225a7753942930f1f7f30 100644 (file)
@@ -178,12 +178,25 @@ struct acct {
 
 /*--------------------------------------------------------------------*/
 
+#define L0(n)
+#define L1(n)                  int n;
+#define MAC_STAT(n, t, l, f, e)        L##l(n)
+struct dstat {
+#include "stat_field.h"
+};
+#undef MAC_STAT
+#undef L0
+#undef L1
+
+/*--------------------------------------------------------------------*/
+
 struct worker {
        unsigned                magic;
 #define WORKER_MAGIC           0x6391adcf
        struct objhead          *nobjhead;
        struct object           *nobj;
        struct objcore          *nobjcore;
+       struct dstat            *stats;
 
        double                  lastused;
 
@@ -551,6 +564,7 @@ void PipeSession(struct sess *sp);
 void WRK_Init(void);
 int WRK_Queue(struct workreq *wrq);
 void WRK_QueueSession(struct sess *sp);
+void WRK_SumStat(struct worker *w);
 
 void WRW_Reserve(struct worker *w, int *fd);
 void WRW_Release(struct worker *w);
index 8f5e7cd29a7b7cb57989b0f4d3b867f2f3cd7465..a64762edab21032424bf7495111ce98c61013cb0 100644 (file)
@@ -181,7 +181,7 @@ cnt_deliver(struct sess *sp)
 
        RES_WriteObj(sp);
        AZ(sp->wrk->wfd);
-       HSH_Deref(&sp->obj);
+       HSH_Deref(sp->wrk, &sp->obj);
        sp->step = STP_DONE;
        return (0);
 }
@@ -527,7 +527,7 @@ cnt_hit(struct sess *sp)
        }
 
        /* Drop our object, we won't need it */
-       HSH_Deref(&sp->obj);
+       HSH_Deref(sp->wrk, &sp->obj);
 
        switch(sp->handling) {
        case VCL_RET_PASS:
@@ -611,7 +611,7 @@ cnt_lookup(struct sess *sp)
        if (sp->obj->objcore->flags & OC_F_PASS) {
                VSL_stats->cache_hitpass++;
                WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
-               HSH_Deref(&sp->obj);
+               HSH_Deref(sp->wrk, &sp->obj);
                sp->step = STP_PASS;
                return (0);
        }
index b96c831c0e9b7d69fe09d26079c46397b10dca86..41f4804d72f52378adf4e56ce15a800a415e9124 100644 (file)
@@ -217,16 +217,20 @@ exp_timer(void *arg)
        double t;
        struct sess *sp;
        unsigned char logbuf[1024];             /* XXX size ? */
+       struct dstat stats;
 
        THR_SetName("cache-timeout");
        (void)arg;
 
        sp = SES_New(NULL, 0);
        XXXAN(sp);
+       memset(&ww, 0, sizeof ww);
+       memset(&stats, 0, sizeof stats);
        sp->wrk = &ww;
        ww.magic = WORKER_MAGIC;
        ww.wlp = ww.wlb = logbuf;
        ww.wle = logbuf + sizeof logbuf;
+       ww.stats = &stats;
 
        AZ(sleep(10));          /* XXX: Takes time for VCL to arrive */
        VCL_Get(&sp->vcl);
@@ -238,6 +242,7 @@ exp_timer(void *arg)
                if (oc == NULL || oc->timer_when > t) { /* XXX: > or >= ? */
                        Lck_Unlock(&exp_mtx);
                        WSL_Flush(&ww, 0);
+                       WRK_SumStat(&ww);
                        AZ(sleep(1));
                        VCL_Refresh(&sp->vcl);
                        t = TIM_real();
@@ -277,7 +282,7 @@ exp_timer(void *arg)
                oc->flags &= ~OC_F_ONLRU;
                VSL_stats->n_expired++;
                Lck_Unlock(&exp_mtx);
-               HSH_Deref(&o);
+               HSH_Deref(&ww, &o);
        }
 }
 
@@ -344,7 +349,7 @@ EXP_NukeOne(struct sess *sp)
 
        if (sp->handling == VCL_RET_DISCARD) {
                WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid);
-               HSH_Deref(&o);
+               HSH_Deref(sp->wrk, &o);
                return (1);
        }
 
index 3b704fe43b4497b70c3b1ee53b10979f030c465e..f416e28d2a335425ce6c8e67a2a88d77e0efea37 100644 (file)
@@ -109,7 +109,7 @@ HSH_Prealloc(struct sess *sp)
                VTAILQ_INIT(&oh->waitinglist);
                Lck_New(&oh->mtx);
                w->nobjhead = oh;
-               VSL_stats->n_objecthead++;
+               w->stats->n_objecthead++;
        }
        CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC);
 
@@ -134,20 +134,20 @@ HSH_Prealloc(struct sess *sp)
                VTAILQ_INIT(&o->store);
                VTAILQ_INIT(&o->esibits);
                w->nobj = o;
-               VSL_stats->n_object++;
+               w->stats->n_object++;
 
        }
        CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
 }
 
 void
-HSH_DeleteObjHead(struct objhead *oh)
+HSH_DeleteObjHead(struct worker *w, struct objhead *oh)
 {
 
        AZ(oh->refcnt);
        assert(VTAILQ_EMPTY(&oh->objcs));
        Lck_Delete(&oh->mtx);
-       VSL_stats->n_objecthead--;
+       w->stats->n_objecthead--;
        free(oh->hash);
        FREE_OBJ(oh);
 }
@@ -398,7 +398,7 @@ HSH_Drop(struct sess *sp)
        o->cacheable = 0;
        if (o->objcore != NULL)         /* Pass has no objcore */
                HSH_Unbusy(sp);
-       HSH_Deref(&sp->obj);
+       HSH_Deref(sp->wrk, &sp->obj);
 }
 
 void
@@ -434,7 +434,7 @@ HSH_Unbusy(const struct sess *sp)
        if (oh != NULL)
                Lck_Unlock(&oh->mtx);
        if (parent != NULL)
-               HSH_Deref(&parent);
+               HSH_Deref(sp->wrk, &parent);
 }
 
 void
@@ -452,7 +452,7 @@ HSH_Ref(struct object *o)
 }
 
 void
-HSH_Deref(struct object **oo)
+HSH_Deref(struct worker *w, struct object **oo)
 {
        struct object *o;
        struct objhead *oh;
@@ -498,7 +498,7 @@ HSH_Deref(struct object **oo)
        ESI_Destroy(o);
        HSH_Freestore(o);
        STV_free(o->objstore);
-       VSL_stats->n_object--;
+       w->stats->n_object--;
 
        if (oh == NULL) {
                AZ(oc);
@@ -510,7 +510,7 @@ HSH_Deref(struct object **oo)
        assert(oh->refcnt > 0);
        if (hash->deref(oh))
                return;
-       HSH_DeleteObjHead(oh);
+       HSH_DeleteObjHead(w, oh);
 }
 
 void
index 881ba0a65f3e71cbab4d53c3e83eda229f451227..5c3b363d4b4caf7de935b3c440fd191dd51c0b57 100644 (file)
@@ -98,6 +98,7 @@ static unsigned                       nthr_max;
 
 static pthread_cond_t          herder_cond;
 static struct lock             herder_mtx;
+static struct lock             wstat_mtx;
 
 /*--------------------------------------------------------------------
  * Write data to fd
@@ -264,6 +265,31 @@ WRW_Sendfile(struct worker *w, int fd, off_t off, unsigned len)
 
 /*--------------------------------------------------------------------*/
 
+static void
+wrk_sumstat(struct worker *w)
+{
+
+       Lck_AssertHeld(&wstat_mtx);
+#define L0(n)
+#define L1(n) VSL_stats->n += w->stats->n 
+#define MAC_STAT(n, t, l, f, d) L##l(n);
+#include "stat_field.h"
+#undef MAC_STAT
+#undef L0
+#undef L1
+       memset(w->stats, 0, sizeof *w->stats);
+}
+
+void
+WRK_SumStat(struct worker *w)
+{
+       Lck_Lock(&wstat_mtx);
+       wrk_sumstat(w);
+       Lck_Unlock(&wstat_mtx);
+}
+
+/*--------------------------------------------------------------------*/
+
 static void *
 wrk_thread(void *priv)
 {
@@ -271,12 +297,16 @@ wrk_thread(void *priv)
        struct wq *qp;
        unsigned char wlog[params->shm_workspace];
        struct SHA256Context sha256;
+       struct dstat stats;
+       unsigned stats_clean = 0;
 
        THR_SetName("cache-worker");
        w = &ww;
        CAST_OBJ_NOTNULL(qp, priv, WQ_MAGIC);
        memset(w, 0, sizeof *w);
+       memset(&stats, 0, sizeof stats);
        w->magic = WORKER_MAGIC;
+       w->stats = &stats;
        w->lastused = NAN;
        w->wlb = w->wlp = wlog;
        w->wle = wlog + sizeof wlog;
@@ -299,6 +329,12 @@ wrk_thread(void *priv)
                        if (isnan(w->lastused))
                                w->lastused = TIM_real();
                        VTAILQ_INSERT_HEAD(&qp->idle, w, list);
+                       if (!stats_clean) {
+                               Lck_Lock(&wstat_mtx);
+                               wrk_sumstat(w);
+                               stats_clean = 1;
+                               Lck_Unlock(&wstat_mtx);
+                       }
                        Lck_CondWait(&w->cond, &qp->mtx);
                }
                if (w->wrq == NULL)
@@ -307,14 +343,21 @@ wrk_thread(void *priv)
                AN(w->wrq);
                AN(w->wrq->func);
                w->lastused = NAN;
+               stats_clean = 0;
                w->wrq->func(w, w->wrq->priv);
                AZ(w->wfd);
                assert(w->wlp == w->wlb);
                w->wrq = NULL;
+               if (!Lck_Trylock(&wstat_mtx)) {
+                       wrk_sumstat(w);
+                       stats_clean = 1;
+                       Lck_Unlock(&wstat_mtx);
+               }
                Lck_Lock(&qp->mtx);
        }
        qp->nthr--;
        Lck_Unlock(&qp->mtx);
+       AN(stats_clean);
 
        VSL(SLT_WorkThread, 0, "%p end", w);
        if (w->vcl != NULL)
@@ -627,6 +670,7 @@ WRK_Init(void)
 
        AZ(pthread_cond_init(&herder_cond, NULL));
        Lck_New(&herder_mtx);
+       Lck_New(&wstat_mtx);
 
        wrk_addpools(params->wthread_pools);
        AZ(pthread_create(&tp, NULL, wrk_herdtimer_thread, NULL));
index 40d77da4b381da792327d0014e3638449782cc10..5b3f4fbeae4c128f196f77efad41554972061a0a 100644 (file)
@@ -345,6 +345,13 @@ hcb_cleaner(void *priv)
 {
        struct objhead *oh, *oh2;
        struct hcb_y *y;
+       struct worker ww;
+       struct dstat stats;
+
+       memset(&ww, 0, sizeof ww);
+       memset(&stats, 0, sizeof stats);
+       ww.magic = WORKER_MAGIC;
+       ww.stats = &stats;
 
        THR_SetName("hcb_cleaner");
        (void)priv;
@@ -361,10 +368,11 @@ hcb_cleaner(void *priv)
                                fprintf(stderr, "OH %p is cold enough\n", oh);
 #endif
                                oh->refcnt = 0;
-                               HSH_DeleteObjHead(oh);
+                               HSH_DeleteObjHead(&ww, oh);
                        }
                }
                Lck_Unlock(&hcb_mtx);
+               WRK_SumStat(&ww);
        }
 }
 
index 3e96e74f5d7282f170bab47555f4b49b87c1f0e8..c52bc4d03fc40a1dc0d5beec27f1b32d211b9213 100644 (file)
@@ -50,13 +50,11 @@ struct hash_slinger {
 
 /* cache_hash.c */
 void HSH_Prealloc(struct sess *sp);
-void HSH_DeleteObjHead(struct objhead *oh);
 void HSH_Freestore(struct object *o);
 void HSH_Copy(const struct sess *sp, struct objhead *o);
 struct object *HSH_Lookup(struct sess *sp);
 void HSH_Unbusy(const struct sess *sp);
 void HSH_Ref(struct object *o);
-void HSH_Deref(struct object **o);
 void HSH_Drop(struct sess *sp);
 double HSH_Grace(double g);
 void HSH_Init(void);
@@ -100,4 +98,6 @@ struct objhead {
 };
 
 extern unsigned        save_hash;
+void HSH_DeleteObjHead(struct worker *w, struct objhead *oh);
+void HSH_Deref(struct worker *w, struct object **o);
 #endif /* VARNISH_CACHE_CHILD */
index f5043b4a264ad4e5059667de33f493dd34017270..ee0c5b33de1c0a6500e6de2b23ef0c99e53b431f 100644 (file)
@@ -49,8 +49,8 @@ MAC_STAT(n_srcaddr,           uint64_t, 0, 'i', "N struct srcaddr")
 MAC_STAT(n_srcaddr_act,                uint64_t, 0, 'i', "N active struct srcaddr")
 MAC_STAT(n_sess_mem,           uint64_t, 0, 'i', "N struct sess_mem")
 MAC_STAT(n_sess,               uint64_t, 0, 'i', "N struct sess")
-MAC_STAT(n_object,             uint64_t, 0, 'i', "N struct object")
-MAC_STAT(n_objecthead,         uint64_t, 0, 'i', "N struct objecthead")
+MAC_STAT(n_object,             uint64_t, 1, 'i', "N struct object")
+MAC_STAT(n_objecthead,         uint64_t, 1, 'i', "N struct objecthead")
 MAC_STAT(n_smf,                        uint64_t, 0, 'i', "N struct smf")
 MAC_STAT(n_smf_frag,           uint64_t, 0, 'i', "N small free smf")
 MAC_STAT(n_smf_large,          uint64_t, 0, 'i', "N large free smf")