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);
*/
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@ --- *
*
*/
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);
}
/* 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; }
/* --- @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.
* 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;
* 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);
}
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);
}