chiark / gitweb /
@@@ sink bench
[mLib] / test / tvec-core.c
index 3938397b07d6315d37dbce488d3620b4a35411bf..a25d6532d9b43dec077e80e225b3c8414daf1a44 100644 (file)
@@ -207,77 +207,6 @@ end:
   return (rc);
 }
 
-/*----- Benchmarking ------------------------------------------------------*/
-
-struct bench_state *tvec_benchstate;
-
-struct benchrun {
-  unsigned long *n;
-  tvec_testfn *fn;
-  const struct tvec_reg *in; struct tvec_reg *out;
-  void *ctx;
-};
-
-static void benchloop_outer(unsigned long n, void *p)
-  { struct benchrun *r = p; while (n--) r->fn(r->in, r->out, r->ctx); }
-
-static void benchloop_inner(unsigned long n, void *p)
-  { struct benchrun *r = p; *r->n = n; r->fn(r->in, r->out, r->ctx); }
-
-int tvec_ensurebench(struct tvec_state *tv, struct bench_state **b_out)
-{
-  const struct tvec_bench *tvb = tv->test->arg.p;
-  struct bench_state **bb;
-  struct bench_timer *bt;
-
-  if (tvb->b) bb = tvb->b;
-  else bb = &tvec_benchstate;
-
-  if (!*bb) {
-    bt = bench_createtimer();
-    if (!bt) { tvec_skip(tv, "failed to create timer"); return (-1); }
-    *bb = xmalloc(sizeof(**bb)); bench_init(*bb, bt);
-  } else if (!(*bb)->tm)
-    { tvec_skip(tv, "failed to create timer"); return (-1); }
-
-  *b_out = *bb;
-  return (0);
-}
-
-int tvec_bench(struct tvec_state *tv)
-{
-  const struct tvec_bench *tvb = tv->test->arg.p;
-  struct bench_state *b;
-  struct bench_timing tm;
-  struct benchrun r;
-  bench_fn *loopfn;
-
-  if (tvec_ensurebench(tv, &b)) goto end_0;
-
-  r.in = tv->in; r.out = tv->out; r.fn = tv->test->fn;
-  if (tvb->ctxsz) r.ctx = xmalloc(tvb->ctxsz);
-  else r.ctx = 0;
-  if (tvb->setup && tvb->setup(tv->in, tv->out, &tvb->arg, r.ctx))
-    { tvec_skip(tv, "benchmark setup failed"); goto end_1; }
-
-  if (tvb->riter < 0)
-    { r.n = 0; loopfn = benchloop_outer; }
-  else
-    { r.n = &TVEC_REG(tv, in, tvb->riter)->v.u; loopfn = benchloop_inner; }
-
-  tv->output->ops->bbench(tv->output);
-  if (bench_measure(&tm, b, loopfn, &r))
-    { tv->output->ops->ebench(tv->output, 0); goto end_2; }
-  tv->output->ops->ebench(tv->output, &tm);
-
-end_2:
-  if (tvb->teardown) tvb->teardown(r.ctx);
-end_1:
-  if (r.ctx) xfree(r.ctx);
-end_0:
-  return (0);
-}
-
 /*----- Main machinery ----------------------------------------------------*/
 
 void tvec_skipspc(struct tvec_state *tv)
@@ -622,6 +551,77 @@ end:
   return (rc);
 }
 
+/*----- Benchmarking ------------------------------------------------------*/
+
+struct bench_state *tvec_benchstate;
+
+struct benchrun {
+  unsigned long *n;
+  tvec_testfn *fn;
+  const struct tvec_reg *in; struct tvec_reg *out;
+  void *ctx;
+};
+
+static void benchloop_outer(unsigned long n, void *p)
+  { struct benchrun *r = p; while (n--) r->fn(r->in, r->out, r->ctx); }
+
+static void benchloop_inner(unsigned long n, void *p)
+  { struct benchrun *r = p; *r->n = n; r->fn(r->in, r->out, r->ctx); }
+
+int tvec_ensurebench(struct tvec_state *tv, struct bench_state **b_out)
+{
+  const struct tvec_bench *tvb = tv->test->arg.p;
+  struct bench_state **bb;
+  struct bench_timer *bt;
+
+  if (tvb->b) bb = tvb->b;
+  else bb = &tvec_benchstate;
+
+  if (!*bb) {
+    bt = bench_createtimer();
+    if (!bt) { tvec_skip(tv, "failed to create timer"); return (-1); }
+    *bb = xmalloc(sizeof(**bb)); bench_init(*bb, bt);
+  } else if (!(*bb)->tm)
+    { tvec_skip(tv, "failed to create timer"); return (-1); }
+
+  *b_out = *bb;
+  return (0);
+}
+
+int tvec_bench(struct tvec_state *tv)
+{
+  const struct tvec_bench *tvb = tv->test->arg.p;
+  struct bench_state *b;
+  struct bench_timing tm;
+  struct benchrun r;
+  bench_fn *loopfn;
+
+  if (tvec_ensurebench(tv, &b)) goto end_0;
+
+  r.in = tv->in; r.out = tv->out; r.fn = tv->test->fn;
+  if (tvb->ctxsz) r.ctx = xmalloc(tvb->ctxsz);
+  else r.ctx = 0;
+  if (tvb->setup && tvb->setup(tv->in, tv->out, &tvb->arg, r.ctx))
+    { tvec_skip(tv, "benchmark setup failed"); goto end_1; }
+
+  if (tvb->riter < 0)
+    { r.n = 0; loopfn = benchloop_outer; }
+  else
+    { r.n = &TVEC_REG(tv, in, tvb->riter)->v.u; loopfn = benchloop_inner; }
+
+  tv->output->ops->bbench(tv->output);
+  if (bench_measure(&tm, b, loopfn, &r))
+    { tv->output->ops->ebench(tv->output, 0); goto end_2; }
+  tv->output->ops->ebench(tv->output, &tm);
+
+end_2:
+  if (tvb->teardown) tvb->teardown(r.ctx);
+end_1:
+  if (r.ctx) xfree(r.ctx);
+end_0:
+  return (0);
+}
+
 /*----- Ad-hoc testing ----------------------------------------------------*/
 
 static const struct tvec_regdef no_regs = { 0, 0, 0, 0, { 0 } };