From ab39a8fde94c7a07ae5f512d6788e23ac1679763 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 26 Jan 2026 01:56:36 -0600 Subject: [PATCH] runners: Adopted compile-time optional kiwibd as emubd alternative kiwibd has been used extensively in external benchmarks, it makes sense to make it the default bd for the bench runner: - test_runner - defaults to emubd - more testing features - bench_runner - defaults to kiwibd - lighter-weight disks The benefit of kiwibd is the disk is just one big blob of RAM, so basically no overhead. This is important when benchmarking on multi-GiB disks. emubd is much heavy, but as a tradeoff can do quite a bit more: bad-block simulation, wear simulation, snapshotting, etc. --- In theory the bd used by each runner can be controlled at compile-time by defining -DBENCH_EMUBD, etc, but I have a feeling no one will ever use this. --- runners/bench_defines.h | 8 +- runners/bench_runner.c | 142 ++++++++++++++++++++++++++------ runners/bench_runner.h | 24 ++++++ runners/test_defines.h | 8 +- runners/test_runner.c | 176 +++++++++++++++++++++++++++++++--------- runners/test_runner.h | 24 ++++++ 6 files changed, 312 insertions(+), 70 deletions(-) diff --git a/runners/bench_defines.h b/runners/bench_defines.h index a7ba00b0..3d5a79a8 100644 --- a/runners/bench_defines.h +++ b/runners/bench_defines.h @@ -61,10 +61,12 @@ BENCH_DEFINE(PROGGED_TIMING, 1484 ) BENCH_DEFINE(ERASED_TIMING, 0 ) #endif + #ifndef BENCH_KIWIBD BENCH_DEFINE(ERASE_CYCLES, 0 ) BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) - BENCH_DEFINE(EMUBD_SEED, 0 ) + BENCH_DEFINE(BD_SEED, 0 ) + #endif #endif @@ -107,9 +109,11 @@ BENCH_BDCFG(readed_timing, READED_TIMING ) BENCH_BDCFG(progged_timing, PROGGED_TIMING ) BENCH_BDCFG(erased_timing, ERASED_TIMING ) + #ifndef BENCH_KIWIBD BENCH_BDCFG(erase_cycles, ERASE_CYCLES ) BENCH_BDCFG(badblock_behavior, BADBLOCK_BEHAVIOR ) BENCH_BDCFG(powerloss_behavior, POWERLOSS_BEHAVIOR ) - BENCH_BDCFG(seed, EMUBD_SEED ) + BENCH_BDCFG(seed, BD_SEED ) + #endif #endif diff --git a/runners/bench_runner.c b/runners/bench_runner.c index 86821063..28bbc0c2 100644 --- a/runners/bench_runner.c +++ b/runners/bench_runner.c @@ -9,7 +9,6 @@ #endif #include "runners/bench_runner.h" -#include "bd/lfs3_emubd.h" #include #include @@ -22,6 +21,21 @@ #include #include #include +#include + + +// some common types +#ifndef BENCH_KIWIBD +typedef lfs3_emubd_io_t bench_io_t; +typedef lfs3_emubd_sio_t bench_sio_t; +typedef lfs3_emubd_ns_t bench_ns_t; +typedef lfs3_emubd_sns_t bench_sns_t; +#else +typedef lfs3_kiwibd_io_t bench_io_t; +typedef lfs3_kiwibd_sio_t bench_sio_t; +typedef lfs3_kiwibd_ns_t bench_ns_t; +typedef lfs3_kiwibd_sns_t bench_sns_t; +#endif // some helpers @@ -436,9 +450,9 @@ FILE *bench_trace_file = NULL; uint32_t bench_trace_cycles = 0; uint64_t bench_trace_time = 0; uint64_t bench_trace_open_time = 0; -lfs3_emubd_ns_t bench_read_sleep = 0.0; -lfs3_emubd_ns_t bench_prog_sleep = 0.0; -lfs3_emubd_ns_t bench_erase_sleep = 0.0; +bench_ns_t bench_read_sleep = 0.0; +bench_ns_t bench_prog_sleep = 0.0; +bench_ns_t bench_erase_sleep = 0.0; // this determines both the backtrace buffer and the trace printf buffer, if // trace ends up interleaved or truncated this may need to be increased @@ -603,13 +617,13 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size) { // bench recording state typedef struct bench_record { const char *probe; - lfs3_emubd_io_t last_reads; - lfs3_emubd_io_t last_progs; - lfs3_emubd_io_t last_erases; - lfs3_emubd_io_t last_readed; - lfs3_emubd_io_t last_progged; - lfs3_emubd_io_t last_erased; - lfs3_emubd_ns_t last_simtime; + bench_io_t last_reads; + bench_io_t last_progs; + bench_io_t last_erases; + bench_io_t last_readed; + bench_io_t last_progged; + bench_io_t last_erased; + bench_ns_t last_simtime; } bench_record_t; static struct lfs3_cfg *bench_cfg = NULL; @@ -625,20 +639,37 @@ void bench_reset(struct lfs3_cfg *cfg) { void bench_start(const char *probe) { // measure current read/prog/erase assert(bench_cfg); - lfs3_emubd_sio_t reads = lfs3_emubd_reads(bench_cfg); + #ifndef BENCH_KIWIBD + bench_sio_t reads = lfs3_emubd_reads(bench_cfg); assert(reads >= 0); - lfs3_emubd_sio_t progs = lfs3_emubd_progs(bench_cfg); + bench_sio_t progs = lfs3_emubd_progs(bench_cfg); assert(progs >= 0); - lfs3_emubd_sio_t erases = lfs3_emubd_erases(bench_cfg); + bench_sio_t erases = lfs3_emubd_erases(bench_cfg); assert(erases >= 0); - lfs3_emubd_sio_t readed = lfs3_emubd_readed(bench_cfg); + bench_sio_t readed = lfs3_emubd_readed(bench_cfg); assert(readed >= 0); - lfs3_emubd_sio_t progged = lfs3_emubd_progged(bench_cfg); + bench_sio_t progged = lfs3_emubd_progged(bench_cfg); assert(progged >= 0); - lfs3_emubd_sio_t erased = lfs3_emubd_erased(bench_cfg); + bench_sio_t erased = lfs3_emubd_erased(bench_cfg); assert(erased >= 0); // note this can error if no timings provided - lfs3_emubd_sns_t simtime = lfs3_emubd_simtime(bench_cfg); + bench_sns_t simtime = lfs3_emubd_simtime(bench_cfg); + #else + bench_sio_t reads = lfs3_kiwibd_reads(bench_cfg); + assert(reads >= 0); + bench_sio_t progs = lfs3_kiwibd_progs(bench_cfg); + assert(progs >= 0); + bench_sio_t erases = lfs3_kiwibd_erases(bench_cfg); + assert(erases >= 0); + bench_sio_t readed = lfs3_kiwibd_readed(bench_cfg); + assert(readed >= 0); + bench_sio_t progged = lfs3_kiwibd_progged(bench_cfg); + assert(progged >= 0); + bench_sio_t erased = lfs3_kiwibd_erased(bench_cfg); + assert(erased >= 0); + // note this can error if no timings provided + bench_sns_t simtime = lfs3_kiwibd_simtime(bench_cfg); + #endif // allocate a new record bench_record_t *record = mappend( @@ -659,20 +690,37 @@ void bench_start(const char *probe) { void bench_stop(const char *probe, uintmax_t n) { // measure current read/prog/erase assert(bench_cfg); - lfs3_emubd_sio_t reads = lfs3_emubd_reads(bench_cfg); + #ifndef BENCH_KIWIBD + bench_sio_t reads = lfs3_emubd_reads(bench_cfg); assert(reads >= 0); - lfs3_emubd_sio_t progs = lfs3_emubd_progs(bench_cfg); + bench_sio_t progs = lfs3_emubd_progs(bench_cfg); assert(progs >= 0); - lfs3_emubd_sio_t erases = lfs3_emubd_erases(bench_cfg); + bench_sio_t erases = lfs3_emubd_erases(bench_cfg); assert(erases >= 0); - lfs3_emubd_sio_t readed = lfs3_emubd_readed(bench_cfg); + bench_sio_t readed = lfs3_emubd_readed(bench_cfg); assert(readed >= 0); - lfs3_emubd_sio_t progged = lfs3_emubd_progged(bench_cfg); + bench_sio_t progged = lfs3_emubd_progged(bench_cfg); assert(progged >= 0); - lfs3_emubd_sio_t erased = lfs3_emubd_erased(bench_cfg); + bench_sio_t erased = lfs3_emubd_erased(bench_cfg); assert(erased >= 0); // note this can error if no timings provided - lfs3_emubd_sns_t simtime = lfs3_emubd_simtime(bench_cfg); + bench_sns_t simtime = lfs3_emubd_simtime(bench_cfg); + #else + bench_sio_t reads = lfs3_kiwibd_reads(bench_cfg); + assert(reads >= 0); + bench_sio_t progs = lfs3_kiwibd_progs(bench_cfg); + assert(progs >= 0); + bench_sio_t erases = lfs3_kiwibd_erases(bench_cfg); + assert(erases >= 0); + bench_sio_t readed = lfs3_kiwibd_readed(bench_cfg); + assert(readed >= 0); + bench_sio_t progged = lfs3_kiwibd_progged(bench_cfg); + assert(progged >= 0); + bench_sio_t erased = lfs3_kiwibd_erased(bench_cfg); + assert(erased >= 0); + // note this can error if no timings provided + bench_sns_t simtime = lfs3_kiwibd_simtime(bench_cfg); + #endif // find our record for (size_t i = 0; i < bench_record_count; i++) { @@ -1383,20 +1431,33 @@ void perm_run( } // create block device and configuration + #ifndef BENCH_KIWIBD lfs3_emubd_t bd; + #else + lfs3_kiwibd_t bd; + #endif struct lfs3_cfg cfg = { .context = &bd, + #ifndef BENCH_KIWIBD .read = lfs3_emubd_read, .prog = lfs3_emubd_prog, .erase = lfs3_emubd_erase, .sync = lfs3_emubd_sync, + #else + .read = lfs3_kiwibd_read, + .prog = lfs3_kiwibd_prog, + .erase = lfs3_kiwibd_erase, + .sync = lfs3_kiwibd_sync, + #endif #define BENCH_CFG(k, v) \ .k = v, #include "bench_defines.h" #undef BENCH_CFG }; + // using emubd? + #ifndef BENCH_KIWIBD struct lfs3_emubd_cfg bdcfg = { .read_sleep = bench_read_sleep, .prog_sleep = bench_prog_sleep, @@ -1409,10 +1470,29 @@ void perm_run( int err = lfs3_emubd_createcfg(&cfg, bench_disk_path, &bdcfg); if (err) { - fprintf(stderr, "error: could not create block device: %d\n", err); + fprintf(stderr, "error: could not create emubd: %d\n", err); exit(-1); } + // using kiwibd? + #else + struct lfs3_kiwibd_cfg bdcfg = { + .read_sleep = bench_read_sleep, + .prog_sleep = bench_prog_sleep, + .erase_sleep = bench_erase_sleep, + #define BENCH_BDCFG(k, v) \ + .k = v, + #include "bench_defines.h" + #undef BENCH_CFG + }; + + int err = lfs3_kiwibd_createcfg(&cfg, bench_disk_path, &bdcfg); + if (err) { + fprintf(stderr, "error: could not create kiwibd: %d\n", err); + exit(-1); + } + #endif + // run the bench bench_reset(&cfg); printf("running "); @@ -1426,11 +1506,19 @@ void perm_run( printf("\n"); // cleanup + #ifndef BENCH_KIWIBD err = lfs3_emubd_destroy(&cfg); if (err) { - fprintf(stderr, "error: could not destroy block device: %d\n", err); + fprintf(stderr, "error: could not destroy emubd: %d\n", err); exit(-1); } + #else + err = lfs3_kiwibd_destroy(&cfg); + if (err) { + fprintf(stderr, "error: could not destroy kiwibd: %d\n", err); + exit(-1); + } + #endif } static void run(void) { diff --git a/runners/bench_runner.h b/runners/bench_runner.h index 01f1129f..f7cb8e1c 100644 --- a/runners/bench_runner.h +++ b/runners/bench_runner.h @@ -8,6 +8,23 @@ #define BENCH_RUNNER_H +// default to using kiwibd for benches +#if !defined(BENCH_EMUBD) && !defined(BENCH_KIWIBD) +#define BENCH_KIWIBD +#endif + +// ifdef macros for emubd vs kiwibd +#ifdef BENCH_EMUBD +#define BENCH_IFDEF_EMUBD(a, b) (a) +#else +#define BENCH_IFDEF_EMUBD(a, b) (b) +#endif +#ifdef BENCH_KIWIBD +#define BENCH_IFDEF_KIWIBD(a, b) (a) +#else +#define BENCH_IFDEF_KIWIBD(a, b) (b) +#endif + // override LFS3_TRACE void bench_trace(const char *fmt, ...); @@ -18,6 +35,7 @@ void bench_trace(const char *fmt, ...); __VA_ARGS__) #define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "") #define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "") +#define LFS3_KIWIBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "") // BENCH_START/BENCH_STOP macros measure readed/progged/erased bytes // through emubd @@ -36,8 +54,14 @@ void bench_fresult(const char *probe, uintmax_t n, double result); // note these are indirectly included in any generated files +#ifndef BENCH_KIWIBD #include "bd/lfs3_emubd.h" +#else +#include "bd/lfs3_kiwibd.h" +#endif + #include +#include // give source a chance to define feature macros #undef _FEATURES_H diff --git a/runners/test_defines.h b/runners/test_defines.h index afdc4a96..525df9fb 100644 --- a/runners/test_defines.h +++ b/runners/test_defines.h @@ -25,10 +25,12 @@ TEST_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) TEST_DEFINE(LOOKGBMAP_THRESH, BLOCK_COUNT/4 ) TEST_DEFINE(ERASE_VALUE, 0xff ) + #ifndef TEST_KIWIBD TEST_DEFINE(ERASE_CYCLES, 0 ) TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) - TEST_DEFINE(EMUBD_SEED, 0 ) + TEST_DEFINE(BD_SEED, 0 ) + #endif #endif @@ -65,9 +67,11 @@ // struct lfs3_*bd_cfg fields #ifdef TEST_BDCFG TEST_BDCFG(erase_value, ERASE_VALUE ) + #ifndef TEST_KIWIBD TEST_BDCFG(erase_cycles, ERASE_CYCLES ) TEST_BDCFG(badblock_behavior, BADBLOCK_BEHAVIOR ) TEST_BDCFG(powerloss_behavior, POWERLOSS_BEHAVIOR ) - TEST_BDCFG(seed, EMUBD_SEED ) + TEST_BDCFG(seed, BD_SEED ) + #endif #endif diff --git a/runners/test_runner.c b/runners/test_runner.c index bdb1bb5f..5a0616d0 100644 --- a/runners/test_runner.c +++ b/runners/test_runner.c @@ -9,7 +9,6 @@ #endif #include "runners/test_runner.h" -#include "bd/lfs3_emubd.h" #include #include @@ -22,6 +21,21 @@ #include #include #include +#include + + +// some common types +#ifndef TEST_KIWIBD +typedef lfs3_emubd_ns_t test_ns_t; +typedef lfs3_emubd_sns_t test_sns_t; +typedef lfs3_emubd_powercycles_t test_powercycles_t; +typedef lfs3_emubd_spowercycles_t test_spowercycles_t; +#else +typedef lfs3_kiwibd_ns_t test_ns_t; +typedef lfs3_kiwibd_sns_t test_sns_t; +typedef void test_powercycles_t; +typedef void test_spowercycles_t; +#endif // some helpers @@ -117,7 +131,7 @@ typedef struct test_powerloss { const struct test_powerloss *powerloss, const struct test_suite *suite, const struct test_case *case_); - const lfs3_emubd_powercycles_t *cycles; + const test_powercycles_t *cycles; size_t cycle_count; } test_powerloss_t; @@ -447,9 +461,9 @@ FILE *test_trace_file = NULL; uint32_t test_trace_cycles = 0; uint64_t test_trace_time = 0; uint64_t test_trace_open_time = 0; -lfs3_emubd_ns_t test_read_sleep = 0.0; -lfs3_emubd_ns_t test_prog_sleep = 0.0; -lfs3_emubd_ns_t test_erase_sleep = 0.0; +test_ns_t test_read_sleep = 0.0; +test_ns_t test_prog_sleep = 0.0; +test_ns_t test_erase_sleep = 0.0; volatile size_t TEST_PLS = 0; @@ -620,9 +634,11 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size) { static void perm_printid( const struct test_suite *suite, const struct test_case *case_, - const lfs3_emubd_powercycles_t *cycles, + const test_powercycles_t *cycles, size_t cycle_count) { (void)suite; + (void)cycles; + (void)cycle_count; // case[:permutation[:powercycles]] printf("%s:", case_->name); for (size_t d = 0; d < test_define_count; d++) { @@ -633,12 +649,14 @@ static void perm_printid( } // only print power-cycles if any occured + #ifndef TEST_KIWIBD if (cycle_count) { printf(":"); for (size_t i = 0; i < cycle_count; i++) { leb16_print(cycles[i]); } } + #endif } @@ -701,10 +719,12 @@ static void run_powerloss_none( const test_powerloss_t *powerloss, const struct test_suite *suite, const struct test_case *case_); +#ifndef TEST_KIWIBD static void run_powerloss_cycles( const test_powerloss_t *powerloss, const struct test_suite *suite, const struct test_case *case_); +#endif // iterate through permutations in a test case static void case_forperm( @@ -1304,20 +1324,33 @@ static void run_powerloss_none( (void)powerloss; // create block device and configuration + #ifndef TEST_KIWIBD lfs3_emubd_t bd; + #else + lfs3_kiwibd_t bd; + #endif struct lfs3_cfg cfg = { .context = &bd, + #ifndef TEST_KIWIBD .read = lfs3_emubd_read, .prog = lfs3_emubd_prog, .erase = lfs3_emubd_erase, .sync = lfs3_emubd_sync, + #else + .read = lfs3_kiwibd_read, + .prog = lfs3_kiwibd_prog, + .erase = lfs3_kiwibd_erase, + .sync = lfs3_kiwibd_sync, + #endif #define TEST_CFG(k, v) \ .k = v, #include "test_defines.h" #undef TEST_CFG }; + // using emubd? + #ifndef TEST_KIWIBD struct lfs3_emubd_cfg bdcfg = { .read_sleep = test_read_sleep, .prog_sleep = test_prog_sleep, @@ -1330,10 +1363,29 @@ static void run_powerloss_none( int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg); if (err) { - fprintf(stderr, "error: could not create block device: %d\n", err); + fprintf(stderr, "error: could not create emubd: %d\n", err); exit(-1); } + // using kiwibd? + #else + struct lfs3_kiwibd_cfg bdcfg = { + .read_sleep = test_read_sleep, + .prog_sleep = test_prog_sleep, + .erase_sleep = test_erase_sleep, + #define TEST_BDCFG(k, v) \ + .k = v, + #include "test_defines.h" + #undef TEST_CFG + }; + + int err = lfs3_kiwibd_createcfg(&cfg, test_disk_path, &bdcfg); + if (err) { + fprintf(stderr, "error: could not create kiwibd: %d\n", err); + exit(-1); + } + #endif + // run the test printf("running "); perm_printid(suite, case_, NULL, 0); @@ -1349,18 +1401,29 @@ static void run_powerloss_none( printf("\n"); // cleanup + #ifndef TEST_KIWIBD err = lfs3_emubd_destroy(&cfg); if (err) { - fprintf(stderr, "error: could not destroy block device: %d\n", err); + fprintf(stderr, "error: could not destroy emubd: %d\n", err); exit(-1); } + #else + err = lfs3_kiwibd_destroy(&cfg); + if (err) { + fprintf(stderr, "error: could not destroy kiwibd: %d\n", err); + exit(-1); + } + #endif } +#ifndef TEST_KIWIBD static void powerloss_longjmp(void *c) { jmp_buf *powerloss_jmp = c; longjmp(*powerloss_jmp, 1); } +#endif +#ifndef TEST_KIWIBD static void run_powerloss_linear( const test_powerloss_t *powerloss, const struct test_suite *suite, @@ -1401,7 +1464,7 @@ static void run_powerloss_linear( int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg); if (err) { - fprintf(stderr, "error: could not create block device: %d\n", err); + fprintf(stderr, "error: could not create emubd: %d\n", err); exit(-1); } @@ -1438,11 +1501,13 @@ static void run_powerloss_linear( // cleanup err = lfs3_emubd_destroy(&cfg); if (err) { - fprintf(stderr, "error: could not destroy block device: %d\n", err); + fprintf(stderr, "error: could not destroy emubd: %d\n", err); exit(-1); } } +#endif +#ifndef TEST_KIWIBD static void run_powerloss_log( const test_powerloss_t *powerloss, const struct test_suite *suite, @@ -1483,7 +1548,7 @@ static void run_powerloss_log( int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg); if (err) { - fprintf(stderr, "error: could not create block device: %d\n", err); + fprintf(stderr, "error: could not create emubd: %d\n", err); exit(-1); } @@ -1520,11 +1585,13 @@ static void run_powerloss_log( // cleanup err = lfs3_emubd_destroy(&cfg); if (err) { - fprintf(stderr, "error: could not destroy block device: %d\n", err); + fprintf(stderr, "error: could not destroy emubd: %d\n", err); exit(-1); } } +#endif +#ifndef TEST_KIWIBD static void run_powerloss_cycles( const test_powerloss_t *powerloss, const struct test_suite *suite, @@ -1565,7 +1632,7 @@ static void run_powerloss_cycles( int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg); if (err) { - fprintf(stderr, "error: could not create block device: %d\n", err); + fprintf(stderr, "error: could not create emubd: %d\n", err); exit(-1); } @@ -1601,11 +1668,13 @@ static void run_powerloss_cycles( // cleanup err = lfs3_emubd_destroy(&cfg); if (err) { - fprintf(stderr, "error: could not destroy block device: %d\n", err); + fprintf(stderr, "error: could not destroy emubd: %d\n", err); exit(-1); } } +#endif +#ifndef TEST_KIWIBD struct powerloss_exhaustive_state { struct lfs3_cfg *cfg; @@ -1613,13 +1682,17 @@ struct powerloss_exhaustive_state { size_t branch_count; size_t branch_capacity; }; +#endif +#ifndef TEST_KIWIBD struct powerloss_exhaustive_cycles { - lfs3_emubd_powercycles_t *cycles; + test_powercycles_t *cycles; size_t cycle_count; size_t cycle_capacity; }; +#endif +#ifndef TEST_KIWIBD static void powerloss_exhaustive_branch(void *c) { struct powerloss_exhaustive_state *state = c; // append to branches @@ -1636,14 +1709,16 @@ static void powerloss_exhaustive_branch(void *c) { // create copy-on-write copy int err = lfs3_emubd_cpy(state->cfg, branch); if (err) { - fprintf(stderr, "error: exhaustive: could not create bd copy\n"); + fprintf(stderr, "error: exhaustive: could not create emubd copy\n"); exit(-1); } // also trigger on next power cycle lfs3_emubd_setpowercycles(state->cfg, 1); } +#endif +#ifndef TEST_KIWIBD static void run_powerloss_exhaustive_layer( struct powerloss_exhaustive_cycles *cycles, const struct test_suite *suite, @@ -1673,16 +1748,16 @@ static void run_powerloss_exhaustive_layer( // aggressively clean up memory here to try to keep our memory usage low int err = lfs3_emubd_destroy(cfg); if (err) { - fprintf(stderr, "error: could not destroy block device: %d\n", err); + fprintf(stderr, "error: could not destroy emubd: %d\n", err); exit(-1); } // recurse into each branch for (size_t i = 0; i < state.branch_count; i++) { // first push and print the branch - lfs3_emubd_powercycles_t *cycle = mappend( + test_powercycles_t *cycle = mappend( (void**)&cycles->cycles, - sizeof(lfs3_emubd_powercycles_t), + sizeof(test_powercycles_t), &cycles->cycle_count, &cycles->cycle_capacity); if (!cycle) { @@ -1708,7 +1783,9 @@ static void run_powerloss_exhaustive_layer( // clean up memory free(state.branches); } +#endif +#ifndef TEST_KIWIBD static void run_powerloss_exhaustive( const test_powerloss_t *powerloss, const struct test_suite *suite, @@ -1742,7 +1819,7 @@ static void run_powerloss_exhaustive( int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg); if (err) { - fprintf(stderr, "error: could not create block device: %d\n", err); + fprintf(stderr, "error: could not create emubd: %d\n", err); exit(-1); } @@ -1761,33 +1838,44 @@ static void run_powerloss_exhaustive( perm_printid(suite, case_, NULL, 0); printf("\n"); } +#endif const test_powerloss_t builtin_powerlosses[] = { {"none", run_powerloss_none, NULL, 0}, + #ifndef TEST_KIWIBD {"log", run_powerloss_log, NULL, SIZE_MAX}, {"linear", run_powerloss_linear, NULL, SIZE_MAX}, {"exhaustive", run_powerloss_exhaustive, NULL, SIZE_MAX}, + #endif {NULL, NULL, NULL, 0}, }; const char *const builtin_powerlosses_help[] = { - "Run with no power-losses.", - "Run with exponentially-decreasing power-losses.", - "Run with linearly-decreasing power-losses.", - "Run a all permutations of power-losses, this may take a while.", - "Run a all permutations of n power-losses.", - "Run a custom comma-separated set of power-losses.", - "Run a custom leb16-encoded set of power-losses.", + "Run with no powerlosses.", + #ifndef TEST_KIWIBD + "Run with exponentially-decreasing powerlosses.", + "Run with linearly-decreasing powerlosses.", + "Run all powerloss permutations, this may take a while.", + "Run all permutations of n powerlosses.", + "Run custom comma-separated set of powerlosses.", + "Run custom leb16-encoded set of powerlosses.", + #endif }; // default to -Pnone,linear, which provides a good heuristic while still // running quickly const test_powerloss_t *test_powerlosses = (const test_powerloss_t[]){ {"none", run_powerloss_none, NULL, 0}, + #ifndef TEST_KIWIBD {"linear", run_powerloss_linear, NULL, SIZE_MAX}, + #endif }; +#ifndef TEST_KIWIBD size_t test_powerloss_count = 2; +#else +size_t test_powerloss_count = 1; +#endif static void list_powerlosses(void) { // at least size so that names fit @@ -1810,9 +1898,11 @@ static void list_powerlosses(void) { } // a couple more options with special parsing - printf("%-*s %s\n", name_width, "1,2,3", builtin_powerlosses_help[i+0]); - printf("%-*s %s\n", name_width, "{1,2,3}", builtin_powerlosses_help[i+1]); - printf("%-*s %s\n", name_width, ":1248g1", builtin_powerlosses_help[i+2]); + #ifndef TEST_KIWIBD + printf("%-*s %s\n", name_width, "1,2,3", builtin_powerlosses_help[i++]); + printf("%-*s %s\n", name_width, "{1,2,3}", builtin_powerlosses_help[i++]); + printf("%-*s %s\n", name_width, ":1248g1", builtin_powerlosses_help[i++]); + #endif } @@ -2263,17 +2353,18 @@ int main(int argc, char **argv) { } // comma-separated permutation + #ifndef TEST_KIWIBD if (*optarg == '{') { - lfs3_emubd_powercycles_t *cycles = NULL; + test_powercycles_t *cycles = NULL; size_t cycle_count = 0; size_t cycle_capacity = 0; char *s = optarg + 1; while (true) { parsed = NULL; - *(lfs3_emubd_powercycles_t*)mappend( + *(test_powercycles_t*)mappend( (void**)&cycles, - sizeof(lfs3_emubd_powercycles_t), + sizeof(test_powercycles_t), &cycle_count, &cycle_capacity) = strtoumax(s, &parsed, 0); @@ -2298,8 +2389,10 @@ int main(int argc, char **argv) { optarg = s; goto powerloss_next; } + #endif // leb16-encoded permutation + #ifndef TEST_KIWIBD if (*optarg == ':') { // special case for linear power cycles if (optarg[1] == 'x') { @@ -2325,7 +2418,7 @@ int main(int argc, char **argv) { // otherwise explicit power cycles } else { - lfs3_emubd_powercycles_t *cycles = NULL; + test_powercycles_t *cycles = NULL; size_t cycle_count = 0; size_t cycle_capacity = 0; @@ -2337,9 +2430,9 @@ int main(int argc, char **argv) { break; } - *(lfs3_emubd_powercycles_t*)mappend( + *(test_powercycles_t*)mappend( (void**)&cycles, - sizeof(lfs3_emubd_powercycles_t), + sizeof(test_powercycles_t), &cycle_count, &cycle_capacity) = x; s = parsed; @@ -2354,8 +2447,10 @@ int main(int argc, char **argv) { goto powerloss_next; } } + #endif // exhaustive permutations + #ifndef TEST_KIWIBD { parsed = NULL; size_t count = strtoumax(optarg, &parsed, 0); @@ -2370,6 +2465,7 @@ int main(int argc, char **argv) { optarg = (char*)parsed; goto powerloss_next; } + #endif powerloss_unknown:; // unknown scenario? @@ -2580,6 +2676,7 @@ getopt_done:; } // special case for linear power cycles + #ifndef TEST_KIWIBD if (cycles_ && *cycles_ == 'x') { char *parsed = NULL; size_t cycle_count = leb16_parse(cycles_+1, &parsed); @@ -2618,14 +2715,14 @@ getopt_done:; // otherwise explicit power cycles } else if (cycles_) { // parse power cycles - lfs3_emubd_powercycles_t *cycles = NULL; + test_powercycles_t *cycles = NULL; size_t cycle_count = 0; size_t cycle_capacity = 0; while (*cycles_ != '\0') { char *parsed = NULL; - *(lfs3_emubd_powercycles_t*)mappend( + *(test_powercycles_t*)mappend( (void**)&cycles, - sizeof(lfs3_emubd_powercycles_t), + sizeof(test_powercycles_t), &cycle_count, &cycle_capacity) = leb16_parse(cycles_, &parsed); @@ -2644,6 +2741,7 @@ getopt_done:; cycles, cycle_count}; } + #endif } // append to identifier list diff --git a/runners/test_runner.h b/runners/test_runner.h index b6c94bc3..2d69a68e 100644 --- a/runners/test_runner.h +++ b/runners/test_runner.h @@ -8,6 +8,23 @@ #define TEST_RUNNER_H +// default to using emubd for tests +#if !defined(TEST_EMUBD) && !defined(TEST_KIWIBD) +#define TEST_EMUBD +#endif + +// ifdef macros for emubd vs kiwibd +#ifdef TEST_EMUBD +#define TEST_IFDEF_EMUBD(a, b) (a) +#else +#define TEST_IFDEF_EMUBD(a, b) (b) +#endif +#ifdef TEST_KIWIBD +#define TEST_IFDEF_KIWIBD(a, b) (a) +#else +#define TEST_IFDEF_KIWIBD(a, b) (b) +#endif + // override LFS3_TRACE void test_trace(const char *fmt, ...); @@ -18,11 +35,18 @@ void test_trace(const char *fmt, ...); __VA_ARGS__) #define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "") #define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "") +#define LFS3_KIWIBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "") // note these are indirectly included in any generated files +#ifndef TEST_KIWIBD #include "bd/lfs3_emubd.h" +#else +#include "bd/lfs3_kiwibd.h" +#endif + #include +#include // give source a chance to define feature macros #undef _FEATURES_H