tvec_skipgroup(tv, "failed to create timer"); goto end;
}
-/* --- @tvec_benchset@ --- *
+/* --- @tvec_benchfindvar@, @setvar@ --- *
*
* Arguments: @struct tvec_state *tv@ = test vector state
* @const char *var@ = variable name to set
+ * @const union tvec_regval *rv@ = register value
+ * @void **ctx_out@ = where to put the @setvar@ context
* @void *ctx@ = context pointer
*
- * Returns: %$+1$% on success, %$0$% if the variable name was not
- * recognized, or %$-1$% on any other error.
+ * Returns: @tvec_benchfindvar@ returns a pointer to the variable
+ * definition, or null; @setvar@ returns zero on success or
+ * %$-1$% on error.
*
- * Use: Set a special variable. The following special variables are
- * supported.
+ * Use: Find a definition for a special variable. The following
+ * special variables are supported.
*
- * * %|@target|% is the (approximate) number of seconds to run
+ * * %|@target|% is the (approximate) duration to run
* the benchmark.
*
* Unrecognized variables are passed to the subordinate
* environment, if there is one.
*/
-int tvec_benchset(struct tvec_state *tv, const char *var, void *ctx)
+static int setvar(struct tvec_state *tv, const char *var,
+ const union tvec_regval *rv, void *ctx)
{
struct tvec_benchctx *bc = ctx;
- const struct tvec_benchenv *be = bc->be;
- const struct tvec_env *subenv = be->env;
- union tvec_regval rv;
- static const struct tvec_floatinfo fi = { TVFF_NOMAX, 0.0, 0.0, 0.0 };
- static const struct tvec_regdef rd =
- { "@target", -1, &tvty_float, 0, { &fi } };
if (STRCMP(var, ==, "@target")) {
if (bc->f&TVBF_SETTRG) return (tvec_dupreg(tv, var));
- if (tvty_float.parse(&rv, &rd, tv)) return (-1);
- bc->bst->target_s = rv.f; bc->f |= TVBF_SETTRG; return (1);
- } else if (subenv && subenv->set)
- return (subenv->set(tv, var, bc->subctx));
- else
- return (0);
+ bc->bst->target_s = rv->f; bc->f |= TVBF_SETTRG;
+ } else assert("unknown var");
+ return (0);
+}
+
+static const struct tvec_vardef target_var =
+ { sizeof(struct tvec_reg), setvar, { "@target", -1, &tvty_duration, 0 } };
+
+const struct tvec_vardef *tvec_benchfindvar
+ (struct tvec_state *tv, const char *var, void **ctx_out, void *ctx)
+{
+ struct tvec_benchctx *bc = ctx;
+ const struct tvec_benchenv *be = bc->be;
+ const struct tvec_env *subenv = be->env;
+
+ if (STRCMP(var, ==, "@target")) { *ctx_out = bc; return (&target_var); }
+ else if (subenv && subenv->findvar)
+ return (subenv->findvar(tv, var, ctx_out, bc->subctx));
+ else return (0);
}
/* --- @tvec_benchbefore@ --- *
const struct tvec_benchenv *be = bc->be;
const struct tvec_env *subenv = be->env;
- /* Just call the subsidiary environment. */
if (subenv && subenv->before) subenv->before(tv, bc->subctx);
}