@@@ mostly bench docs
[mLib] / test / bench.c
index 2ac63b4..493f227 100644 (file)
@@ -963,7 +963,7 @@ struct bench_timer *bench_createtimer(const char *config)
     if (select_timer(t, i, tmconf[i].p, tmconf[i].sz)) goto end;
 
   /* All is done. */
-  t->_t.ops = &timer_ops; ret = &t->_t; t = 0;
+  t->_t.ops = &timer_ops; t->_t.ref = 1; ret = &t->_t; t = 0;
 end:
   if (t) timer_destroy(&t->_t);
   return (ret);
@@ -1017,7 +1017,7 @@ end:
  */
 
 void bench_destroy(struct bench_state *b)
-  { if (b->tm) { b->tm->ops->destroy(b->tm); b->tm = 0; } }
+  { if (b->tm && !--b->tm->ref) { b->tm->ops->destroy(b->tm); b->tm = 0; } }
 
 /* --- @spin@ --- *
  *
@@ -1080,7 +1080,7 @@ int bench_calibrate(struct bench_state *b, unsigned f)
    */
   if (f&BTF_INDIRECT) {
     for (i = 0; i < 50; i++)
-      BENCH_TIMELOOP_TAG(setup, b, &delta, 10000)
+      BENCH_TIMELOOP_TAG(setup, b->tm, &delta, 10000, ;)
        LAUNDER(&spin)(_bench_n, 0);
   }
 
@@ -1093,10 +1093,10 @@ int bench_calibrate(struct bench_state *b, unsigned f)
 
     /* Measure @n@ iterations of the idle loop. */
     if (f&BTF_INDIRECT)
-      BENCH_TIMELOOP_TAG(calibrate, b, &delta, n)
+      BENCH_TIMELOOP_TAG(calibrate, b->tm, &delta, n, ;)
        LAUNDER(&spin)(_bench_n, 0);
     else
-      BENCH_TIMELOOP_TAG(calibrate, b, &delta, n)
+      BENCH_TIMELOOP_TAG(calibrate, b->tm, &delta, n, ;)
        while (_bench_n--) RELAX;
     tf &= delta.f; if (!(tf&BTF_TIMEOK)) { rc = -1; goto end; }
 
@@ -1162,8 +1162,8 @@ int bench_preflight(struct bench_state *b)
 
 /* --- @bench_adapt@ --- *
  *
- * Arguments:  @struct bench_state *b@ = benchmark state
- *             @double *n_inout@ = number of iterations, updated
+ * Arguments:  @double *n_inout@ = number of iterations, updated
+ *             @double target_s@ = target time in seconds
  *             @const struct bench_timing *t@ = timing from the previous run
  *
  * Returns:    Nonzero if the measurement is sufficient; zero to run again.
@@ -1182,15 +1182,15 @@ int bench_preflight(struct bench_state *b)
  *             On entry, @*n_inout@ should be the number of iterations
  *             performed by the previous pass, and @*t@ the resulting time;
  *             the @BTF_TIMEOK@ flag must be set @t->f@.  If the timing is
- *             sufficient -- @t->t@ is sufficiently close to @b->target_s@
+ *             sufficient -- @t->t@ is sufficiently close to @target_s@
  *             -- then the function returns nonzero to indicate that
  *             measurement is complete.  Otherwise, it sets @*n_inout@ to a
  *             new, larger iteration count and returns zero to indicate that
  *             a further pass is necessary.
  */
 
-int bench_adapt(struct bench_state *b,
-               double *n_inout, const struct bench_timing *t)
+int bench_adapt(double *n_inout, double target_s,
+               const struct bench_timing *t)
 {
   double n = *n_inout, nn;
 
@@ -1208,8 +1208,8 @@ int bench_adapt(struct bench_state *b,
    * hand, if %$T/t < 1 + 1/n$% then %$t (n + 1)/n > T$%, so just trying
    * again with %$n' = n + 1$% iterations will very likely work.
    */
-  if (t->t >= 0.707*b->target_s) return (1);
-  nn = n*b->target_s/t->t; modf(nn, &nn);
+  if (t->t >= 0.707*target_s) return (1);
+  nn = n*target_s/t->t; modf(nn, &nn);
   *n_inout = nn > n ? nn : n + 1;
   return (0);
 }
@@ -1279,8 +1279,7 @@ int bench_measure(struct bench_state *b, struct bench_timing *t_out,
   BENCH_MEASURE_DECLS;
   int rc;
 
-  BENCH_MEASURE_TAG(bench_measure, b, rc, t_out, base)
-    fn(_bench_n, ctx);
+  BENCH_MEASURE(b, rc, t_out, base) fn(_bench_n, ctx);
   return (rc);
 }