void cache_get_stats (struct cache *cache, tstat_t *ts, int *sizep, int *incompletep, int *dirtyp) { zlist_t *keys; struct cache_entry *hp; char *ref; int size = 0; int incomplete = 0; int dirty = 0; if (!(keys = zhash_keys (cache->zh))) oom (); while ((ref = zlist_pop (keys))) { hp = zhash_lookup (cache->zh, ref); if (cache_entry_get_valid (hp)) { int obj_size = strlen (Jtostr (hp->o)); size += obj_size; tstat_push (ts, obj_size); } else incomplete++; if (cache_entry_get_dirty (hp)) dirty++; free (ref); } zlist_destroy (&keys); if (sizep) *sizep = size; if (incompletep) *incompletep = incomplete; if (dirtyp) *dirtyp = dirty; }
/* Handle responses */ void ping_continuation (flux_rpc_t *rpc, void *arg) { struct ping_ctx *ctx = arg; const char *json_str, *route, *pad; int64_t sec, nsec; struct timespec t0; int seq; json_object *out = NULL; struct ping_data *pdata = flux_rpc_aux_get (rpc); tstat_t *tstat = pdata->tstat; if (flux_rpc_get (rpc, &json_str) < 0) { log_err ("flux_rpc_get"); goto done; } if (!(out = Jfromstr (json_str)) || !Jget_int (out, "seq", &seq) || !Jget_int64 (out, "time.tv_sec", &sec) || !Jget_int64 (out, "time.tv_nsec", &nsec) || !Jget_str (out, "pad", &pad) || !Jget_str (out, "route", &route) || strcmp (ctx->pad, pad) != 0) { log_err ("error decoding ping response"); goto done; } t0.tv_sec = sec; t0.tv_nsec = nsec; tstat_push (tstat, monotime_since (t0)); pdata->seq = seq; if (pdata->route) free (pdata->route); pdata->route = xstrdup (route); pdata->rpc_count++; done: if (flux_rpc_next (rpc) < 0 && pdata->rpc_count) { if (ctx->rank != NULL) { printf ("%s!%s pad=%lu seq=%d time=(%0.3f:%0.3f:%0.3f) ms stddev %0.3f\n", ctx->rank, ctx->topic, strlen (ctx->pad), pdata->seq, tstat_min (tstat), tstat_mean (tstat), tstat_max (tstat), tstat_stddev (tstat)); } else { char s[16]; snprintf (s, sizeof (s), "%u", ctx->nodeid); printf ("%s%s%s pad=%lu seq=%d time=%0.3f ms (%s)\n", ctx->nodeid == FLUX_NODEID_ANY ? "" : s, ctx->nodeid == FLUX_NODEID_ANY ? "" : "!", ctx->topic, strlen (ctx->pad), pdata->seq, tstat_mean (tstat), pdata->route); } flux_rpc_destroy (rpc); } Jput (out); }
int main (int argc, char *argv[]) { thd_t *thd; int i, rc; int ch; tstat_t ts; struct timespec t0; log_init (basename (argv[0])); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 'f': fopt = true; fence_nprocs = strtoul (optarg, NULL, 10); if (!fence_nprocs) log_msg_exit ("fence value must be > 0"); break; case 's': sopt = true; break; case 'n': nopt = true; nopt_divisor = strtoul (optarg, NULL, 10); if (!nopt_divisor) log_msg_exit ("nopt value must be > 0"); break; default: usage (); } } if (argc - optind != 3) usage (); nthreads = strtoul (argv[optind++], NULL, 10); if (!nthreads) log_msg_exit ("thread count must be > 0"); count = strtoul (argv[optind++], NULL, 10); if (!count) log_msg_exit ("commit count must be > 0"); prefix = argv[optind++]; memset (&ts, 0, sizeof (ts)); thd = xzmalloc (sizeof (*thd) * nthreads); if (sopt) monotime (&t0); for (i = 0; i < nthreads; i++) { thd[i].n = i; if (!(thd[i].perf = zlist_new ())) oom (); if ((rc = pthread_attr_init (&thd[i].attr))) log_errn (rc, "pthread_attr_init"); if ((rc = pthread_create (&thd[i].t, &thd[i].attr, thread, &thd[i]))) log_errn (rc, "pthread_create"); } for (i = 0; i < nthreads; i++) { if ((rc = pthread_join (thd[i].t, NULL))) log_errn (rc, "pthread_join"); if (sopt) { double *e; while ((e = zlist_pop (thd[i].perf))) { tstat_push (&ts, *e); free (e); } } zlist_destroy (&thd[i].perf); } if (sopt) { json_t *o; char *s; if (!(o = json_pack ("{s:{s:i s:f s:f s:f s:f} s:f}", "put+commit times (sec)", "count", tstat_count (&ts), "min", tstat_min (&ts)*1E-3, "mean", tstat_mean (&ts)*1E-3, "stddev", tstat_stddev (&ts)*1E-3, "max", tstat_max (&ts)*1E-3, "put+commit throughput (#/sec)", (double)(count*nthreads) / (monotime_since (t0)*1E-3)))) log_err_exit ("json_pack"); if (!(s = json_dumps (o, JSON_INDENT(2)))) log_err_exit ("json_dumps"); printf ("%s\n", s); json_decref (o); free (s); } free (thd); log_fini (); return 0; }