@@@ bench wip
[mLib] / test / bench.h
index c0627e2..bca3b01 100644 (file)
 #  include "bits.h"
 #endif
 
+#ifndef MLIB_DSTR_H
+#  include "dstr.h"
+#endif
+
 /*----- Data structures ---------------------------------------------------*/
 
 struct bench_time {
@@ -57,6 +61,9 @@ struct bench_timing {
 struct bench_timer { const struct bench_timerops *ops; };
 
 struct bench_timerops {
+  void (*describe)(struct bench_timer */*bt*/, dstr */*d*/);
+    /* Write a description of the timer to @d@. */
+
   void (*now)(struct bench_timer */*bt*/, struct bench_time */*t_out*/);
     /* Fill in @*t_out@ with the current time. v*/
 
@@ -68,6 +75,7 @@ struct bench_state {
   struct bench_timer *tm;              /* a timer */
   double target_s;                     /* target time to run benchmarks */
   unsigned f;                          /* calibration flags (@BTF_...@) */
+#define BTF_CLB 0x0100                 /*   tried calibrating */
   struct { double m, c; } clk, cy;     /* calculated overheads */
 };
 
@@ -78,32 +86,41 @@ typedef void bench_fn(unsigned long /*n*/, void */*ctx*/);
 
 /* --- @bench_createtimer@ --- *
  *
- * Arguments:  ---
+ * Arguments:  @const char *config@ = user-supplied configuration string
  *
- * Returns:    A freshly constructed standard timer object.
+ * Returns:    A freshly constructed standard timer object, or null on
+ *             failure.
  *
  * Use:                Allocate a timer.  Dispose of it by calling
  *             @tm->ops->destroy(tm)@ when you're done.
+ *
+ *             Applications should not set configuration strings except as
+ *             established by user action, e.g., from a command-line option,
+ *             environment variable, or configuration file.
  */
 
-extern struct bench_timer *bench_createtimer(void);
+extern struct bench_timer *bench_createtimer(const char *config);
 
 /* --- @bench_init@ --- *
  *
  * Arguments:  @struct bench_state *b@ = bench state to initialize
- *             @struct bench_timer *tm@ = timer to attach
+ *             @struct bench_timer *tm@ = timer to attach, or null
  *
- * Returns:    ---
+ * Returns:    Zero on success, %$-1$% on failure.
+ *
+ * Use:                Initialize the benchmark state.  On success, the timer state
+ *             still needs to be calibrated (use @bench_calibrate@) before
+ *             it can be used, but this will be done automatically by
+ *             @bench_measure@ if it's not done by hand earlier.  The timer
+ *             is now owned by the benchmark state and will be destroyed by
+ *             @bench_destroy@.
  *
- * Use:                Initialize the benchmark state.  It still needs to be
- *             calibrated (use @bench_calibrate@) before it can be used, but
- *             this will be done automatically by @bench_measure@ if it's
- *             not done by hand earlier.  The timer is now owned by the
- *             benchmark state and will be destroyed by @bench_destroy@.
+ *             The only reason for failure is if @tm@ was null on entry,
+ *             and automatic construction of a timer failed.  The state is
+ *             safe to discard, but calling @bench_destroy@ is safe too.
  */
 
-extern void bench_init(struct bench_state */*b*/,
-                      struct bench_timer */*tm*/);
+extern int bench_init(struct bench_state */*b*/, struct bench_timer */*tm*/);
 
 /* --- @bench_destroy@ --- *
  *
@@ -121,7 +138,7 @@ extern void bench_destroy(struct bench_state */*b*/);
  *
  * Arguments:  @struct bench_state *b@ = bench state
  *
- * Returns:    Zero on success, @-1@ if calibration failed.
+ * Returns:    Zero on success, %$-1$% if calibration failed.
  *
  * Use:                Calibrate the benchmark state, so that it can be used to
  *             measure performance reasonably accurately.
@@ -136,7 +153,7 @@ extern int bench_calibrate(struct bench_state */*b*/);
  *             @double base@ = number of internal units per call
  *             @bench_fn *fn@, @void *ctx@ = benchmark function to run
  *
- * Returns:    Zero on success, @-1@ if timing failed.
+ * Returns:    Zero on success, %$-1$% if timing failed.
  *
  * Use:                Measure a function.  The function @fn@ is called adaptively
  *             with an iteration count @n@ set so as to run for