@@@ bench wip
[mLib] / test / tvec-bench.c
index ad23043..c81fd68 100644 (file)
@@ -215,32 +215,48 @@ void tvec_benchsetup(struct tvec_state *tv, const struct tvec_env *env,
   const struct tvec_benchenv *be = (const struct tvec_benchenv *)env;
   const struct tvec_env *subenv = be->env;
   struct bench_timer *bt;
+  dstr d = DSTR_INIT;
 
   /* Basic initialization. */
   bc->be = be; bc->bst = 0; bc->subctx = 0;
 
   /* Set up the benchmarking state if it hasn't been done before. */
-  if (!be->bst || !*be->bst) {
-    bt = bench_createtimer(); if (!bt) goto fail_timer;
-    bc->bst = xmalloc(sizeof(*bc->bst)); bench_init(bc->bst, bt);
-    if (be->bst) *be->bst = bc->bst;
-  } else if (!(*be->bst)->tm)
-    goto fail_timer;
-  else
+  if (be->bst && *be->bst)
     bc->bst = *be->bst;
+  else {
+    bt = bench_createtimer(0);
+    if (!bt)
+      { tvec_skipgroup(tv, "failed to create timer"); goto timer_failed; }
+    bc->bst = xmalloc(sizeof(*bc->bst)); bench_init(bc->bst, bt);
+    *be->bst = bc->bst;
+  }
 
-  /* Set the default target time. */
+  /* If the timer isn't calibrated yet then do that now. */
+  if (!(bc->bst->f&BTF_CLB)) {
+    bc->bst->tm->ops->describe(bc->bst->tm, &d);
+    tvec_notice(tv, "calibrating timer `%s'...", d.buf);
+    if (bench_calibrate(bc->bst))
+      { tvec_skipgroup(tv, "failed to calibrate timer"); goto timer_failed; }
+  } else if (!(bc->bst->f&BTF_ANY))
+    { tvec_skipgroup(tv, "timer broken"); goto timer_failed; }
+
+  /* Save the default target time. */
   bc->dflt_target = bc->bst->target_s;
 
   /* Initialize the subordinate environment. */
+end:
   if (subenv && subenv->ctxsz) bc->subctx = xmalloc(subenv->ctxsz);
   if (subenv && subenv->setup) subenv->setup(tv, subenv, bc, bc->subctx);
 
   /* All done. */
-end:
+  dstr_destroy(&d);
   return;
-fail_timer:
-  tvec_skipgroup(tv, "failed to create timer"); goto end;
+
+timer_failed:
+  if (!getenv("MLIB_BENCH_DEBUG"))
+    tvec_notice(tv, "set `MLIB_BENCH_DEBUG=t' in the environment "
+               "for more detail");
+  goto end;
 }
 
 /* --- @tvec_benchfindvar@, @setvar@ --- *
@@ -400,7 +416,7 @@ void tvec_benchafter(struct tvec_state *tv, void *ctx)
   const struct tvec_env *subenv = be->env;
 
   /* Restore the benchmark state's old target. */
-  bc->bst->target_s = bc->dflt_target;
+  if (bc->bst) bc->bst->target_s = bc->dflt_target;
   bc->f &= ~TVBF_SETTRG;
 
   /* Pass the call on to the subsidiary environment. */