Files
littlefs/bd/lfs3_kiwibd.h
T
Christopher Haster 4405ad47e4 runners: Reworked test/bench for out-of-tree extensions
The main changes:

- Added TEST_DEFINES and BENCH_DEFINES to allow overriding the default
  test/bench define header:

    -DTEST_DEFINES=my_test_defines.h

  Note these are VERY different from LFS_DEFINES upstream. They aren't a
  typical header file, and are included multiple times with various
  query macros.

  It's hacky, but works surprisingly well.

  Or maybe I'll just do anything to avoid having to write multiline
  macros. Ugh, backslashes.

- Moved more logic into bench/test_defines.h, including everything
  needed to integrate other filesystems out-of-tree.

  This mostly meant moving all of the cfg initialization logic into its
  own query macro (replacing the BENCH/TEST_CFG field macros).

But this also includes a bunch of small tweaks encountered while trying
to get external benchmarks running again.

The external benchmarks include several other filesystems (littlefs2,
SPIFFS, Yaffs2), and I'm hoping this injectable/queryable header thing
will do a good job at avoiding a maintenance headache. (At least a
better job than forking bench_runner.c, which was the previous
solution.)
2026-02-19 13:42:49 -06:00

167 lines
5.1 KiB
C

/*
* kiwibd - A lightweight variant of emubd, useful for emulating large
* disks backed by a file or in RAM.
*
* Unlike emubd, file-backed disks are _not_ mirrored in RAM. kiwibd has
* fewer features than emubd, prioritizing speed for benchmarking.
*
*
*/
#ifndef LFS3_KIWIBD_H
#define LFS3_KIWIBD_H
#include "lfs3.h"
#include "lfs3_util.h"
// Block device specific tracing
#ifndef LFS3_KIWIBD_TRACE
#ifdef LFS3_KIWIBD_YES_TRACE
#define LFS3_KIWIBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_KIWIBD_TRACE(...)
#endif
#endif
// Type for measuring read/program/erase operations
typedef uint64_t lfs3_kiwibd_io_t;
typedef int64_t lfs3_kiwibd_sio_t;
// Type for delays in nanoseconds
typedef uint64_t lfs3_kiwibd_ns_t;
typedef int64_t lfs3_kiwibd_sns_t;
// kiwibd config, this is required for testing
struct lfs3_kiwibd_cfg {
// Optional statically allocated buffer for the block device. Ignored
// if disk_path is provided.
void *buffer;
// 8-bit erase value to use for simulating erases. -1 simulates a noop
// erase, which is faster than simulating a fixed erase value. -2 emulates
// nor-masking, which is useful for testing other filesystems (littlefs
// does _not_ rely on this!).
int32_t erase_value;
// Simulated read transaction timing in nanoseconds, this is added
// to simtime each read call, ignoring the requested size
lfs3_kiwibd_ns_t reads_timing;
// Simulated prog transaction timing in nanoseconds, this is added
// to simtime each prog call, ignoring the requested size
lfs3_kiwibd_ns_t progs_timing;
// Simulated erase transaction timing in nanoseconds, this is added
// to simtime each erase call, ignoring the requested size
lfs3_kiwibd_ns_t erases_timing;
// Simulated read byte timing in nanoseconds, this is scaled by the
// requested size and added to simtime each read call.
lfs3_kiwibd_ns_t readed_timing;
// Simulated prog byte timing in nanoseconds, this is scaled by the
// requested size and added to simtime each prog call.
lfs3_kiwibd_ns_t progged_timing;
// Simulated erase byte timing in nanoseconds, this is scaled by the
// requested size and added to simtime each erase call.
lfs3_kiwibd_ns_t erased_timing;
// Artificial read transaction delay in nanoseconds, there is no
// purpose for this other than slowing down the simulation.
lfs3_kiwibd_ns_t read_sleep;
// Artificial prog transaction delay in nanoseconds, there is no
// purpose for this other than slowing down the simulation.
lfs3_kiwibd_ns_t prog_sleep;
// Artificial erase transaction delay in nanoseconds, there is no
// purpose for this other than slowing down the simulation.
lfs3_kiwibd_ns_t erase_sleep;
};
// kiwibd state
typedef struct lfs3_kiwibd {
// backing disk
int fd;
union {
uint8_t *scratch;
uint8_t *mem;
} u;
// amount read/progged/erased
lfs3_kiwibd_io_t reads;
lfs3_kiwibd_io_t progs;
lfs3_kiwibd_io_t erases;
lfs3_kiwibd_io_t readed;
lfs3_kiwibd_io_t progged;
lfs3_kiwibd_io_t erased;
const struct lfs3_kiwibd_cfg *cfg;
} lfs3_kiwibd_t;
/// Block device API ///
// Create a kiwibd using the geometry in lfs3_cfg
//
// If path is provided, kiwibd will use the file to back the block
// device, allowing emulation of block devices > available RAM.
//
int lfs3_kiwibd_create(const struct lfs3_cfg *cfg, const char *path);
int lfs3_kiwibd_createcfg(const struct lfs3_cfg *cfg, const char *path,
const struct lfs3_kiwibd_cfg *bdcfg);
// Clean up memory associated with block device
int lfs3_kiwibd_destroy(const struct lfs3_cfg *cfg);
// Read a block
int lfs3_kiwibd_read(const struct lfs3_cfg *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs3_kiwibd_prog(const struct lfs3_cfg *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs3_kiwibd_erase(const struct lfs3_cfg *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_kiwibd_sync(const struct lfs3_cfg *cfg);
/// Additional kiwibd features ///
// Get simulated runtime in nanoseconds
lfs3_kiwibd_sns_t lfs3_kiwibd_simtime(const struct lfs3_cfg *cfg);
// Reset simulation counters
int lfs3_kiwibd_simreset(const struct lfs3_cfg *cfg);
// Get total number of read transactions
lfs3_kiwibd_sio_t lfs3_kiwibd_reads(const struct lfs3_cfg *cfg);
// Get total number of prog transactions
lfs3_kiwibd_sio_t lfs3_kiwibd_progs(const struct lfs3_cfg *cfg);
// Get total number of erase transactions
lfs3_kiwibd_sio_t lfs3_kiwibd_erases(const struct lfs3_cfg *cfg);
// Get total amount of bytes read
lfs3_kiwibd_sio_t lfs3_kiwibd_readed(const struct lfs3_cfg *cfg);
// Get total amount of bytes programmed
lfs3_kiwibd_sio_t lfs3_kiwibd_progged(const struct lfs3_cfg *cfg);
// Get total amount of bytes erased
lfs3_kiwibd_sio_t lfs3_kiwibd_erased(const struct lfs3_cfg *cfg);
#endif