Big rename! Renamed lfs -> lfs3 and lfsr -> lfs3

This commit is contained in:
Christopher Haster
2025-05-28 15:00:04 -05:00
parent 3413f125d8
commit 6eba1180c8
50 changed files with 52278 additions and 52111 deletions
+11 -11
View File
@@ -9,21 +9,21 @@
*.gcno
*.gcda
*.perf
lfs
liblfs.a
lfs3
liblfs3.a
# Testing things
runners/test_runner
runners/bench_runner
lfs.code.csv
lfs.data.csv
lfs.stack.csv
lfs.structs.csv
lfs.cov.csv
lfs.perf.csv
lfs.perfbd.csv
lfs.test.csv
lfs.bench.csv
lfs3.code.csv
lfs3.data.csv
lfs3.stack.csv
lfs3.structs.csv
lfs3.cov.csv
lfs3.perf.csv
lfs3.perfbd.csv
lfs3.test.csv
lfs3.bench.csv
# Misc
tags
+69 -69
View File
@@ -2,9 +2,9 @@
BUILDDIR ?= .
# overrideable target, default to building a library
ifneq ($(wildcard test.c main.c),)
TARGET ?= $(BUILDDIR)/lfs
TARGET ?= $(BUILDDIR)/lfs3
else
TARGET ?= $(BUILDDIR)/liblfs.a
TARGET ?= $(BUILDDIR)/liblfs3.a
endif
@@ -82,7 +82,7 @@ else
CFLAGS += -Os
endif
ifdef TRACE
CFLAGS += -DLFS_YES_TRACE
CFLAGS += -DLFS3_YES_TRACE
endif
ifdef COVGEN
CFLAGS += --coverage
@@ -94,8 +94,8 @@ ifdef PERFBDGEN
CFLAGS += -fno-omit-frame-pointer
endif
# also forward all LFS_* environment variables
CFLAGS += $(foreach D,$(filter LFS_%,$(.VARIABLES)),-D$D=$($D))
# also forward all LFS3_* environment variables
CFLAGS += $(foreach D,$(filter LFS3_%,$(.VARIABLES)),-D$D=$($D))
TEST_CFLAGS += -Wno-unused-function
TEST_CFLAGS += -Wno-format-overflow
@@ -231,12 +231,12 @@ code: $(OBJ)
## Save the per-function code size
.PHONY: code-csv
code-csv: $(BUILDDIR)/lfs.code.csv
code-csv: $(BUILDDIR)/lfs3.code.csv
## Compare per-function code size
.PHONY: code-diff
code-diff: $(OBJ)
./scripts/code.py $^ $(CODEFLAGS) -d $(BUILDDIR)/lfs.code.csv
./scripts/code.py $^ $(CODEFLAGS) -d $(BUILDDIR)/lfs3.code.csv
## Find the per-function data size
.PHONY: data
@@ -246,12 +246,12 @@ data: $(OBJ)
## Save the per-function data size
.PHONY: data-csv
data-csv: $(BUILDDIR)/lfs.data.csv
data-csv: $(BUILDDIR)/lfs3.data.csv
## Compare per-function data size
.PHONY: data-diff
data-diff: $(OBJ)
./scripts/data.py $^ $(DATAFLAGS) -d $(BUILDDIR)/lfs.data.csv
./scripts/data.py $^ $(DATAFLAGS) -d $(BUILDDIR)/lfs3.data.csv
## Find the per-function stack usage
.PHONY: stack
@@ -261,12 +261,12 @@ stack: $(CI)
## Save the per-function stack usage
.PHONY: stack-csv
stack-csv: $(BUILDDIR)/lfs.stack.csv
stack-csv: $(BUILDDIR)/lfs3.stack.csv
## Compare per-function stack usage
.PHONY: stack-diff
stack-diff: $(CI)
./scripts/stack.py $^ $(STACKFLAGS) -d $(BUILDDIR)/lfs.stack.csv
./scripts/stack.py $^ $(STACKFLAGS) -d $(BUILDDIR)/lfs3.stack.csv
## Find the per-function context
.PHONY: ctx
@@ -276,12 +276,12 @@ ctx: $(OBJ)
## Save the per-function context
.PHONY: ctx-csv
ctx-csv: $(BUILDDIR)/lfs.ctx.csv
ctx-csv: $(BUILDDIR)/lfs3.ctx.csv
## Compare per-function context
.PHONY: ctx-diff
ctx-diff: $(CI)
./scripts/ctx.py $^ $(CTXFLAGS) -d $(BUILDDIR)/lfs.ctx.csv
./scripts/ctx.py $^ $(CTXFLAGS) -d $(BUILDDIR)/lfs3.ctx.csv
## Find function sizes
.PHONY: funcs
@@ -302,9 +302,9 @@ funcs: $(OBJ) $(CI)
.PHONY: funcs-csv
funcs-csv: SHELL=/bin/bash
funcs-csv: \
$(BUILDDIR)/lfs.code.csv \
$(BUILDDIR)/lfs.stack.csv \
$(BUILDDIR)/lfs.ctx.csv
$(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs3.ctx.csv
## Compare function sizes
.PHONY: funcs-diff
@@ -319,9 +319,9 @@ funcs-diff: $(OBJ) $(CI)
-fstack='max(stack_limit)' \
-fctx='max(ctx_size)' \
-d <(./scripts/csv.py \
$(BUILDDIR)/lfs.code.csv \
$(BUILDDIR)/lfs.stack.csv \
$(BUILDDIR)/lfs.ctx.csv \
$(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs3.ctx.csv \
-fcode_size=code_size \
-fstack_limit='max(stack_limit)' \
-fctx_size='max(ctx_size)' \
@@ -336,12 +336,12 @@ structs: $(OBJ)
## Save struct sizes
.PHONY: structs-csv
structs-csv: $(BUILDDIR)/lfs.structs.csv
structs-csv: $(BUILDDIR)/lfs3.structs.csv
## Compare struct sizes
.PHONY: structs-diff
structs-diff: $(OBJ)
./scripts/structs.py $^ $(STRUCTSFLAGS) -d $(BUILDDIR)/lfs.structs.csv
./scripts/structs.py $^ $(STRUCTSFLAGS) -d $(BUILDDIR)/lfs3.structs.csv
## Find the line/branch coverage after a test run
.PHONY: cov
@@ -353,14 +353,14 @@ cov: $(GCDA)
## Save line/branch coverage
.PHONY: cov-csv
cov-csv: $(BUILDDIR)/lfs.cov.csv
cov-csv: $(BUILDDIR)/lfs3.cov.csv
## Compare line/branch coverage
.PHONY: cov-diff
cov-diff: $(GCDA)
$(strip ./scripts/cov.py $^ \
$(patsubst %,-F%,$(SRC)) \
$(COVFLAGS) -d $(BUILDDIR)/lfs.cov.csv)
$(COVFLAGS) -d $(BUILDDIR)/lfs3.cov.csv)
## Find the perf results after bench run with PERFGEN
.PHONY: perf
@@ -372,14 +372,14 @@ perf: $(BENCH_PERF)
## Save perf results
.PHONY: perf-csv
perf-csv: $(BUILDDIR)/lfs.perf.csv
perf-csv: $(BUILDDIR)/lfs3.perf.csv
## Compare perf results
.PHONY: perf-diff
perf-diff: $(BENCH_PERF)
$(strip ./scripts/perf.py $^ \
$(patsubst %,-F%,$(SRC)) \
$(PERFFLAGS) -d $(BUILDDIR)/lfs.perf.csv)
$(PERFFLAGS) -d $(BUILDDIR)/lfs3.perf.csv)
## Find the perfbd results after a bench run
.PHONY: perfbd
@@ -391,14 +391,14 @@ perfbd: $(BENCH_TRACE)
## Save perfbd results
.PHONY: perfbd-csv
perfbd-csv: $(BUILDDIR)/lfs.perfbd.csv
perfbd-csv: $(BUILDDIR)/lfs3.perfbd.csv
## Compare perfbd results
.PHONY: perfbd-diff
perfbd-diff: $(BENCH_TRACE)
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
$(patsubst %,-F%,$(SRC)) \
$(PERFBDFLAGS) -d $(BUILDDIR)/lfs.perfbd.csv)
$(PERFBDFLAGS) -d $(BUILDDIR)/lfs3.perfbd.csv)
## Find a summary of compile-time sizes
.PHONY: summary sizes
@@ -420,10 +420,10 @@ summary sizes: $(OBJ) $(CI)
.PHONY: summary-csv sizes-csv
summary-csv sizes-csv: SHELL=/bin/bash
summary-csv sizes-csv: \
$(BUILDDIR)/lfs.code.csv \
$(BUILDDIR)/lfs.data.csv \
$(BUILDDIR)/lfs.stack.csv \
$(BUILDDIR)/lfs.ctx.csv
$(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs3.data.csv \
$(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs3.ctx.csv
## Compare compile-time sizes
.PHONY: summary-diff sizes-diff
@@ -442,10 +442,10 @@ summary-diff sizes-diff: $(OBJ) $(CI)
-fctx='max(ctx_size)' \
-o-) \
<(./scripts/csv.py \
$(BUILDDIR)/lfs.code.csv \
$(BUILDDIR)/lfs.data.csv \
$(BUILDDIR)/lfs.stack.csv \
$(BUILDDIR)/lfs.ctx.csv \
$(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs3.data.csv \
$(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs3.ctx.csv \
-bbuild=BEFORE \
-fcode=code_size \
-fdata=data_size \
@@ -458,12 +458,12 @@ summary-diff sizes-diff: $(OBJ) $(CI)
## Generate a codemap svg
.PHONY: codemap
codemap: CODEMAPFLAGS+=-W1400 -H750 --dark
codemap: $(BUILDDIR)/lfs.codemap.svg
codemap: $(BUILDDIR)/lfs3.codemap.svg
## Generate a tiny codemap, where 1 pixel ~= 1 byte
.PHONY: codemap-tiny
codemap-tiny: CODEMAPFLAGS+=--dark
codemap-tiny: $(BUILDDIR)/lfs.codemap_tiny.svg
codemap-tiny: $(BUILDDIR)/lfs3.codemap_tiny.svg
## Build the test-runner
@@ -504,7 +504,7 @@ testmarks: $(TEST_CSV)
## Save the test results
.PHONY: testmarks-csv
testmarks-csv: $(BUILDDIR)/lfs.test.csv
testmarks-csv: $(BUILDDIR)/lfs3.test.csv
## Compare test results against a previous run
.PHONY: testmarks-diff
@@ -513,7 +513,7 @@ testmarks-diff: $(TEST_CSV)
-bsuite \
-fpassed=test_passed \
-ftime=test_time \
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.test.csv)
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs3.test.csv)
## Build the bench-runner
.PHONY: bench-runner build-benches
@@ -554,7 +554,7 @@ benchmarks: $(BENCH_CSV)
## Save the bench results
.PHONY: benchmarks-csv
benchmarks-csv: $(BUILDDIR)/lfs.bench.csv
benchmarks-csv: $(BUILDDIR)/lfs3.bench.csv
## Compare bench results against a previous run
.PHONY: benchmarks-diff
@@ -564,7 +564,7 @@ benchmarks-diff: $(BENCH_CSV)
-freaded=bench_readed \
-fproged=bench_proged \
-ferased=bench_erased \
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.bench.csv)
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs3.bench.csv)
@@ -575,54 +575,54 @@ benchmarks-diff: $(BENCH_CSV)
.SUFFIXES:
.SECONDARY:
$(BUILDDIR)/lfs: $(OBJ)
$(BUILDDIR)/lfs3: $(OBJ)
$(CC) $(CFLAGS) $^ $(LFLAGS) -o$@
$(BUILDDIR)/liblfs.a: $(OBJ)
$(BUILDDIR)/liblfs3.a: $(OBJ)
$(AR) rcs $@ $^
$(BUILDDIR)/lfs.code.csv: $(OBJ)
$(BUILDDIR)/lfs3.code.csv: $(OBJ)
./scripts/code.py $^ $(CODEFLAGS) -o$@
$(BUILDDIR)/lfs.data.csv: $(OBJ)
$(BUILDDIR)/lfs3.data.csv: $(OBJ)
./scripts/data.py $^ $(DATAFLAGS) -o$@
$(BUILDDIR)/lfs.stack.csv: $(CI)
$(BUILDDIR)/lfs3.stack.csv: $(CI)
./scripts/stack.py $^ $(STACKFLAGS) -o$@
$(BUILDDIR)/lfs.ctx.csv: $(OBJ)
$(BUILDDIR)/lfs3.ctx.csv: $(OBJ)
./scripts/ctx.py $^ $(CTXFLAGS) -o$@
$(BUILDDIR)/lfs.structs.csv: $(OBJ)
$(BUILDDIR)/lfs3.structs.csv: $(OBJ)
./scripts/structs.py $^ $(STRUCTSFLAGS) -o$@
$(BUILDDIR)/lfs.cov.csv: $(GCDA)
$(BUILDDIR)/lfs3.cov.csv: $(GCDA)
$(strip ./scripts/cov.py $^ \
$(patsubst %,-F%,$(SRC)) \
$(COVFLAGS) -o$@)
$(BUILDDIR)/lfs.perf.csv: $(BENCH_PERF)
$(BUILDDIR)/lfs3.perf.csv: $(BENCH_PERF)
$(strip ./scripts/perf.py $^ \
$(patsubst %,-F%,$(SRC)) \
$(PERFFLAGS) -o$@)
$(BUILDDIR)/lfs.perfbd.csv: $(BENCH_TRACE)
$(BUILDDIR)/lfs3.perfbd.csv: $(BENCH_TRACE)
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
$(patsubst %,-F%,$(SRC)) \
$(PERFBDFLAGS) -o$@)
$(BUILDDIR)/lfs.codemap.svg: $(OBJ) $(CI)
$(BUILDDIR)/lfs3.codemap.svg: $(OBJ) $(CI)
$(strip ./scripts/codemapsvg.py $^ $(CODEMAPFLAGS) -o$@ \
&& ./scripts/codemap.py $^ --no-header)
$(BUILDDIR)/lfs.codemap_tiny.svg: $(OBJ) $(CI)
$(BUILDDIR)/lfs3.codemap_tiny.svg: $(OBJ) $(CI)
$(strip ./scripts/codemapsvg.py $^ --tiny $(CODEMAPFLAGS) -o$@ \
&& ./scripts/codemap.py $^ --no-header)
$(BUILDDIR)/lfs.test.csv: $(TEST_CSV)
$(BUILDDIR)/lfs3.test.csv: $(TEST_CSV)
cp $^ $@
$(BUILDDIR)/lfs.bench.csv: $(BENCH_CSV)
$(BUILDDIR)/lfs3.bench.csv: $(BENCH_CSV)
cp $^ $@
$(BUILDDIR)/runners/test_runner: $(TEST_OBJ)
@@ -666,20 +666,20 @@ $(BUILDDIR)/%.b.c: %.c $(BENCHES)
## Clean everything
.PHONY: clean
clean:
rm -f $(BUILDDIR)/lfs
rm -f $(BUILDDIR)/liblfs.a
rm -f $(BUILDDIR)/lfs.code.csv
rm -f $(BUILDDIR)/lfs.data.csv
rm -f $(BUILDDIR)/lfs.stack.csv
rm -f $(BUILDDIR)/lfs.ctx.csv
rm -f $(BUILDDIR)/lfs.structs.csv
rm -f $(BUILDDIR)/lfs.cov.csv
rm -f $(BUILDDIR)/lfs.perf.csv
rm -f $(BUILDDIR)/lfs.perfbd.csv
rm -f $(BUILDDIR)/lfs.codemap.svg
rm -f $(BUILDDIR)/lfs.codemap_tiny.svg
rm -f $(BUILDDIR)/lfs.test.csv
rm -f $(BUILDDIR)/lfs.bench.csv
rm -f $(BUILDDIR)/lfs3
rm -f $(BUILDDIR)/liblfs3.a
rm -f $(BUILDDIR)/lfs3.code.csv
rm -f $(BUILDDIR)/lfs3.data.csv
rm -f $(BUILDDIR)/lfs3.stack.csv
rm -f $(BUILDDIR)/lfs3.ctx.csv
rm -f $(BUILDDIR)/lfs3.structs.csv
rm -f $(BUILDDIR)/lfs3.cov.csv
rm -f $(BUILDDIR)/lfs3.perf.csv
rm -f $(BUILDDIR)/lfs3.perfbd.csv
rm -f $(BUILDDIR)/lfs3.codemap.svg
rm -f $(BUILDDIR)/lfs3.codemap_tiny.svg
rm -f $(BUILDDIR)/lfs3.test.csv
rm -f $(BUILDDIR)/lfs3.bench.csv
rm -f $(OBJ)
rm -f $(DEP)
rm -f $(ASM)
File diff suppressed because it is too large Load Diff
+265
View File
@@ -0,0 +1,265 @@
/*
* Emulating block device, wraps filebd and rambd while providing a bunch
* of hooks for testing littlefs in various conditions.
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS3_EMUBD_H
#define LFS3_EMUBD_H
#include "lfs3.h"
#include "lfs3_util.h"
#include "bd/lfs3_rambd.h"
#include "bd/lfs3_filebd.h"
// Block device specific tracing
#ifndef LFS3_EMUBD_TRACE
#ifdef LFS3_EMUBD_YES_TRACE
#define LFS3_EMUBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_EMUBD_TRACE(...)
#endif
#endif
// Mode determining how "bad-blocks" behave during testing. This simulates
// some real-world circumstances such as progs not sticking (prog-noop),
// a readonly disk (erase-noop), ECC failures (read-error), and of course,
// random bit failures (prog-flip, read-flip)
typedef enum lfs3_emubd_badblock_behavior {
LFS3_EMUBD_BADBLOCK_PROGERROR = 0, // Error on prog
LFS3_EMUBD_BADBLOCK_ERASEERROR = 1, // Error on erase
LFS3_EMUBD_BADBLOCK_READERROR = 2, // Error on read
LFS3_EMUBD_BADBLOCK_PROGNOOP = 3, // Prog does nothing silently
LFS3_EMUBD_BADBLOCK_ERASENOOP = 4, // Erase does nothing silently
LFS3_EMUBD_BADBLOCK_PROGFLIP = 5, // Prog flips a bit
LFS3_EMUBD_BADBLOCK_READFLIP = 6, // Read flips a bit sometimes
LFS3_EMUBD_BADBLOCK_MANUAL = 7, // Bits require manual flipping
} lfs3_emubd_badblock_behavior_t;
// Mode determining how power-loss behaves during testing.
typedef enum lfs3_emubd_powerloss_behavior {
LFS3_EMUBD_POWERLOSS_ATOMIC = 0, // Progs are atomic
LFS3_EMUBD_POWERLOSS_SOMEBITS = 1, // One bit is progged
LFS3_EMUBD_POWERLOSS_MOSTBITS = 2, // All-but-one bit is progged
LFS3_EMUBD_POWERLOSS_OOO = 3, // Blocks are written out-of-order
LFS3_EMUBD_POWERLOSS_METASTABLE = 4, // Reads may flip a bit
} lfs3_emubd_powerloss_behavior_t;
// Type for measuring read/program/erase operations
typedef uint64_t lfs3_emubd_io_t;
typedef int64_t lfs3_emubd_sio_t;
// Type for measuring wear
typedef uint32_t lfs3_emubd_wear_t;
typedef int32_t lfs3_emubd_swear_t;
// Type for tracking power-cycles
typedef uint32_t lfs3_emubd_powercycles_t;
typedef int32_t lfs3_emubd_spowercycles_t;
// Type for delays in nanoseconds
typedef uint64_t lfs3_emubd_sleep_t;
typedef int64_t lfs3_emubd_ssleep_t;
// emubd config, this is required for testing
struct lfs3_emubd_config {
// 8-bit erase value to use for simulating erases. -1 simulates a noop
// erase, which is faster than simulating a fixed erase value.
int32_t erase_value;
// Number of erase cycles before a block becomes "bad". The exact behavior
// of bad blocks is controlled by badblock_behavior.
uint32_t erase_cycles;
// The mode determining how bad-blocks fail
lfs3_emubd_badblock_behavior_t badblock_behavior;
// Number of write operations (erase/prog) before triggering a power-loss.
// power_cycles=0 disables this. The exact behavior of power-loss is
// controlled by a combination of powerloss_behavior and powerloss_cb.
lfs3_emubd_powercycles_t power_cycles;
// The mode determining how power-loss affects disk
lfs3_emubd_powerloss_behavior_t powerloss_behavior;
// Function to call to emulate power-loss. The exact behavior of power-loss
// is up to the runner to provide.
void (*powerloss_cb)(void*);
// Data for power-loss callback
void *powerloss_data;
// Seed for prng, which may be used for emulating failed progs. This does
// not affect normal operation.
uint32_t seed;
// Path to file to use as a mirror of the disk. This provides a way to view
// the current state of the block device.
const char *disk_path;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs3_emubd_sleep_t read_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs3_emubd_sleep_t prog_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs3_emubd_sleep_t erase_sleep;
};
// A reference counted block
typedef struct lfs3_emubd_block {
uint32_t rc;
lfs3_emubd_wear_t wear;
bool metastable;
// sign(bad_bit)=0 => randomized on erase
// sign(bad_bit)=1 => fixed
lfs3_size_t bad_bit;
uint8_t data[];
} lfs3_emubd_block_t;
// Disk mirror
typedef struct lfs3_emubd_disk {
uint32_t rc;
int fd;
uint8_t *scratch;
} lfs3_emubd_disk_t;
// emubd state
typedef struct lfs3_emubd {
// array of copy-on-write blocks
lfs3_emubd_block_t **blocks;
// some other test state
lfs3_emubd_io_t readed;
lfs3_emubd_io_t proged;
lfs3_emubd_io_t erased;
uint32_t prng;
lfs3_emubd_powercycles_t power_cycles;
lfs3_emubd_block_t **ooo_before;
lfs3_emubd_block_t **ooo_after;
lfs3_emubd_disk_t *disk;
const struct lfs3_emubd_config *cfg;
} lfs3_emubd_t;
/// Block device API ///
// Create an emulating block device using the geometry in lfs3_config
//
// Note that filebd is used if a path is provided, if path is NULL
// emubd will use rambd which can be much faster.
int lfs3_emubd_create(const struct lfs3_config *cfg, const char *path);
int lfs3_emubd_createcfg(const struct lfs3_config *cfg, const char *path,
const struct lfs3_emubd_config *bdcfg);
// Clean up memory associated with block device
int lfs3_emubd_destroy(const struct lfs3_config *cfg);
// Read a block
int lfs3_emubd_read(const struct lfs3_config *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_emubd_prog(const struct lfs3_config *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_emubd_erase(const struct lfs3_config *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_emubd_sync(const struct lfs3_config *cfg);
/// Additional extended API for driving test features ///
// Set the current prng state
void lfs3_emubd_seed(const struct lfs3_config *cfg, uint32_t seed);
// Get a pseudo-random number from emubd's internal prng
uint32_t lfs3_emubd_prng(const struct lfs3_config *cfg);
// Get total amount of bytes read
lfs3_emubd_sio_t lfs3_emubd_readed(const struct lfs3_config *cfg);
// Get total amount of bytes programmed
lfs3_emubd_sio_t lfs3_emubd_proged(const struct lfs3_config *cfg);
// Get total amount of bytes erased
lfs3_emubd_sio_t lfs3_emubd_erased(const struct lfs3_config *cfg);
// Manually set amount of bytes read
int lfs3_emubd_setreaded(const struct lfs3_config *cfg,
lfs3_emubd_io_t readed);
// Manually set amount of bytes programmed
int lfs3_emubd_setproged(const struct lfs3_config *cfg,
lfs3_emubd_io_t proged);
// Manually set amount of bytes erased
int lfs3_emubd_seterased(const struct lfs3_config *cfg,
lfs3_emubd_io_t erased);
// Get simulated wear on a given block
lfs3_emubd_swear_t lfs3_emubd_wear(const struct lfs3_config *cfg,
lfs3_block_t block);
// Manually set simulated wear on a given block
int lfs3_emubd_setwear(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_emubd_wear_t wear);
// Mark a block as bad, this is equivalent to setting wear to maximum
int lfs3_emubd_markbad(const struct lfs3_config *cfg, lfs3_block_t block);
// Clear any simulated wear on a given block
int lfs3_emubd_markgood(const struct lfs3_config *cfg, lfs3_block_t block);
// Get which bit failed, this changes on erase/power-loss unless manually set
lfs3_ssize_t lfs3_emubd_badbit(const struct lfs3_config *cfg,
lfs3_block_t block);
// Set which bit should fail in a given block
int lfs3_emubd_setbadbit(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_size_t bit);
// Randomize the bad bit on erase (the default)
int lfs3_emubd_randomizebadbit(const struct lfs3_config *cfg,
lfs3_block_t block);
// Mark a block as bad and which bit should fail
int lfs3_emubd_markbadbit(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_size_t bit);
// Flip a bit in a given block, intended for emulating bit errors
int lfs3_emubd_flipbit(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_size_t bit);
// Flip all bits marked as bad
int lfs3_emubd_flip(const struct lfs3_config *cfg);
// Get the remaining power-cycles
lfs3_emubd_spowercycles_t lfs3_emubd_powercycles(
const struct lfs3_config *cfg);
// Manually set the remaining power-cycles
int lfs3_emubd_setpowercycles(const struct lfs3_config *cfg,
lfs3_emubd_powercycles_t power_cycles);
// Create a copy-on-write copy of the state of this block device
int lfs3_emubd_cpy(const struct lfs3_config *cfg, lfs3_emubd_t *copy);
#endif
+42 -42
View File
@@ -5,7 +5,7 @@
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "bd/lfs_filebd.h"
#include "bd/lfs3_filebd.h"
#include <fcntl.h>
#include <unistd.h>
@@ -15,8 +15,8 @@
#include <windows.h>
#endif
int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
LFS_FILEBD_TRACE("lfs_filebd_create(%p {.context=%p, "
int lfs3_filebd_create(const struct lfs3_config *cfg, const char *path) {
LFS3_FILEBD_TRACE("lfs3_filebd_create(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"}, "
@@ -26,7 +26,7 @@ int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
path, (void*)bdcfg, bdcfg->erase_value);
lfs_filebd_t *bd = cfg->context;
lfs3_filebd_t *bd = cfg->context;
// open file
#ifdef _WIN32
@@ -37,39 +37,39 @@ int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
if (bd->fd < 0) {
int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_create -> %d", err);
LFS3_FILEBD_TRACE("lfs3_filebd_create -> %d", err);
return err;
}
LFS_FILEBD_TRACE("lfs_filebd_create -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_create -> %d", 0);
return 0;
}
int lfs_filebd_destroy(const struct lfs_config *cfg) {
LFS_FILEBD_TRACE("lfs_filebd_destroy(%p)", (void*)cfg);
lfs_filebd_t *bd = cfg->context;
int lfs3_filebd_destroy(const struct lfs3_config *cfg) {
LFS3_FILEBD_TRACE("lfs3_filebd_destroy(%p)", (void*)cfg);
lfs3_filebd_t *bd = cfg->context;
int err = close(bd->fd);
if (err < 0) {
err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_destroy -> %d", err);
LFS3_FILEBD_TRACE("lfs3_filebd_destroy -> %d", err);
return err;
}
LFS_FILEBD_TRACE("lfs_filebd_destroy -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_destroy -> %d", 0);
return 0;
}
int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size) {
LFS_FILEBD_TRACE("lfs_filebd_read(%p, "
int lfs3_filebd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size) {
LFS3_FILEBD_TRACE("lfs3_filebd_read(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs_filebd_t *bd = cfg->context;
lfs3_filebd_t *bd = cfg->context;
// check if read is valid
LFS_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->read_size == 0);
LFS_ASSERT(size % cfg->read_size == 0);
LFS_ASSERT(off+size <= cfg->block_size);
LFS3_ASSERT(block < cfg->block_count);
LFS3_ASSERT(off % cfg->read_size == 0);
LFS3_ASSERT(size % cfg->read_size == 0);
LFS3_ASSERT(off+size <= cfg->block_size);
// zero for reproducibility (in case file is truncated)
memset(buffer, 0, size);
@@ -79,73 +79,73 @@ int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
if (res1 < 0) {
int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err);
LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", err);
return err;
}
ssize_t res2 = read(bd->fd, buffer, size);
if (res2 < 0) {
int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err);
LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", err);
return err;
}
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", 0);
return 0;
}
int lfs_filebd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size) {
LFS_FILEBD_TRACE("lfs_filebd_prog(%p, "
int lfs3_filebd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size) {
LFS3_FILEBD_TRACE("lfs3_filebd_prog(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs_filebd_t *bd = cfg->context;
lfs3_filebd_t *bd = cfg->context;
// check if write is valid
LFS_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->prog_size == 0);
LFS_ASSERT(size % cfg->prog_size == 0);
LFS_ASSERT(off+size <= cfg->block_size);
LFS3_ASSERT(block < cfg->block_count);
LFS3_ASSERT(off % cfg->prog_size == 0);
LFS3_ASSERT(size % cfg->prog_size == 0);
LFS3_ASSERT(off+size <= cfg->block_size);
// program data
off_t res1 = lseek(bd->fd,
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
if (res1 < 0) {
int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err);
LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", err);
return err;
}
ssize_t res2 = write(bd->fd, buffer, size);
if (res2 < 0) {
int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err);
LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", err);
return err;
}
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", 0);
return 0;
}
int lfs_filebd_erase(const struct lfs_config *cfg, lfs_block_t block) {
LFS_FILEBD_TRACE("lfs_filebd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
int lfs3_filebd_erase(const struct lfs3_config *cfg, lfs3_block_t block) {
LFS3_FILEBD_TRACE("lfs3_filebd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
(void*)cfg, block, cfg->block_size);
// check if erase is valid
LFS_ASSERT(block < cfg->block_count);
LFS3_ASSERT(block < cfg->block_count);
// erase is a noop
(void)block;
LFS_FILEBD_TRACE("lfs_filebd_erase -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_erase -> %d", 0);
return 0;
}
int lfs_filebd_sync(const struct lfs_config *cfg) {
LFS_FILEBD_TRACE("lfs_filebd_sync(%p)", (void*)cfg);
int lfs3_filebd_sync(const struct lfs3_config *cfg) {
LFS3_FILEBD_TRACE("lfs3_filebd_sync(%p)", (void*)cfg);
// file sync
lfs_filebd_t *bd = cfg->context;
lfs3_filebd_t *bd = cfg->context;
#ifdef _WIN32
int err = FlushFileBuffers((HANDLE) _get_osfhandle(bd->fd)) ? 0 : -1;
#else
@@ -153,10 +153,10 @@ int lfs_filebd_sync(const struct lfs_config *cfg) {
#endif
if (err) {
err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_sync -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_sync -> %d", 0);
return err;
}
LFS_FILEBD_TRACE("lfs_filebd_sync -> %d", 0);
LFS3_FILEBD_TRACE("lfs3_filebd_sync -> %d", 0);
return 0;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Block device emulated in a file
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS3_FILEBD_H
#define LFS3_FILEBD_H
#include "lfs3.h"
#include "lfs3_util.h"
// Block device specific tracing
#ifndef LFS3_FILEBD_TRACE
#ifdef LFS3_FILEBD_YES_TRACE
#define LFS3_FILEBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_FILEBD_TRACE(...)
#endif
#endif
// filebd state
typedef struct lfs3_filebd {
int fd;
} lfs3_filebd_t;
// Create a file block device using the geometry in lfs3_config
int lfs3_filebd_create(const struct lfs3_config *cfg, const char *path);
// Clean up memory associated with block device
int lfs3_filebd_destroy(const struct lfs3_config *cfg);
// Read a block
int lfs3_filebd_read(const struct lfs3_config *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_filebd_prog(const struct lfs3_config *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_filebd_erase(const struct lfs3_config *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_filebd_sync(const struct lfs3_config *cfg);
#endif
+131
View File
@@ -0,0 +1,131 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "bd/lfs3_rambd.h"
int lfs3_rambd_createcfg(const struct lfs3_config *cfg,
const struct lfs3_rambd_config *bdcfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_createcfg(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"}, "
"%p {.buffer=%p})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
(void*)bdcfg, bdcfg->buffer);
lfs3_rambd_t *bd = cfg->context;
bd->cfg = bdcfg;
// allocate buffer?
if (bd->cfg->buffer) {
bd->buffer = bd->cfg->buffer;
} else {
bd->buffer = lfs3_malloc(cfg->block_size * cfg->block_count);
if (!bd->buffer) {
LFS3_RAMBD_TRACE("lfs3_rambd_createcfg -> %d", LFS3_ERR_NOMEM);
return LFS3_ERR_NOMEM;
}
}
// zero for reproducibility
memset(bd->buffer, 0, cfg->block_size * cfg->block_count);
LFS3_RAMBD_TRACE("lfs3_rambd_createcfg -> %d", 0);
return 0;
}
int lfs3_rambd_create(const struct lfs3_config *cfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_create(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count);
static const struct lfs3_rambd_config defaults = {0};
int err = lfs3_rambd_createcfg(cfg, &defaults);
LFS3_RAMBD_TRACE("lfs3_rambd_create -> %d", err);
return err;
}
int lfs3_rambd_destroy(const struct lfs3_config *cfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_destroy(%p)", (void*)cfg);
// clean up memory
lfs3_rambd_t *bd = cfg->context;
if (!bd->cfg->buffer) {
lfs3_free(bd->buffer);
}
LFS3_RAMBD_TRACE("lfs3_rambd_destroy -> %d", 0);
return 0;
}
int lfs3_rambd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size) {
LFS3_RAMBD_TRACE("lfs3_rambd_read(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs3_rambd_t *bd = cfg->context;
// check if read is valid
LFS3_ASSERT(block < cfg->block_count);
LFS3_ASSERT(off % cfg->read_size == 0);
LFS3_ASSERT(size % cfg->read_size == 0);
LFS3_ASSERT(off+size <= cfg->block_size);
// read data
memcpy(buffer, &bd->buffer[block*cfg->block_size + off], size);
LFS3_RAMBD_TRACE("lfs3_rambd_read -> %d", 0);
return 0;
}
int lfs3_rambd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size) {
LFS3_RAMBD_TRACE("lfs3_rambd_prog(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs3_rambd_t *bd = cfg->context;
// check if write is valid
LFS3_ASSERT(block < cfg->block_count);
LFS3_ASSERT(off % cfg->prog_size == 0);
LFS3_ASSERT(size % cfg->prog_size == 0);
LFS3_ASSERT(off+size <= cfg->block_size);
// program data
memcpy(&bd->buffer[block*cfg->block_size + off], buffer, size);
LFS3_RAMBD_TRACE("lfs3_rambd_prog -> %d", 0);
return 0;
}
int lfs3_rambd_erase(const struct lfs3_config *cfg, lfs3_block_t block) {
LFS3_RAMBD_TRACE("lfs3_rambd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
(void*)cfg, block, cfg->block_size);
// check if erase is valid
LFS3_ASSERT(block < cfg->block_count);
// erase is a noop
(void)block;
LFS3_RAMBD_TRACE("lfs3_rambd_erase -> %d", 0);
return 0;
}
int lfs3_rambd_sync(const struct lfs3_config *cfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_sync(%p)", (void*)cfg);
// sync is a noop
(void)cfg;
LFS3_RAMBD_TRACE("lfs3_rambd_sync -> %d", 0);
return 0;
}
+65
View File
@@ -0,0 +1,65 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS3_RAMBD_H
#define LFS3_RAMBD_H
#include "lfs3.h"
#include "lfs3_util.h"
// Block device specific tracing
#ifndef LFS3_RAMBD_TRACE
#ifdef LFS3_RAMBD_YES_TRACE
#define LFS3_RAMBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_RAMBD_TRACE(...)
#endif
#endif
// rambd config (optional)
struct lfs3_rambd_config {
// Optional statically allocated buffer for the block device.
void *buffer;
};
// rambd state
typedef struct lfs3_rambd {
uint8_t *buffer;
const struct lfs3_rambd_config *cfg;
} lfs3_rambd_t;
// Create a RAM block device using the geometry in lfs3_config
int lfs3_rambd_create(const struct lfs3_config *cfg);
int lfs3_rambd_createcfg(const struct lfs3_config *cfg,
const struct lfs3_rambd_config *bdcfg);
// Clean up memory associated with block device
int lfs3_rambd_destroy(const struct lfs3_config *cfg);
// Read a block
int lfs3_rambd_read(const struct lfs3_config *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_rambd_prog(const struct lfs3_config *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_rambd_erase(const struct lfs3_config *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_rambd_sync(const struct lfs3_config *cfg);
#endif
-262
View File
@@ -1,262 +0,0 @@
/*
* Emulating block device, wraps filebd and rambd while providing a bunch
* of hooks for testing littlefs in various conditions.
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_EMUBD_H
#define LFS_EMUBD_H
#include "lfs.h"
#include "lfs_util.h"
#include "bd/lfs_rambd.h"
#include "bd/lfs_filebd.h"
// Block device specific tracing
#ifndef LFS_EMUBD_TRACE
#ifdef LFS_EMUBD_YES_TRACE
#define LFS_EMUBD_TRACE(...) LFS_TRACE(__VA_ARGS__)
#else
#define LFS_EMUBD_TRACE(...)
#endif
#endif
// Mode determining how "bad-blocks" behave during testing. This simulates
// some real-world circumstances such as progs not sticking (prog-noop),
// a readonly disk (erase-noop), ECC failures (read-error), and of course,
// random bit failures (prog-flip, read-flip)
typedef enum lfs_emubd_badblock_behavior {
LFS_EMUBD_BADBLOCK_PROGERROR = 0, // Error on prog
LFS_EMUBD_BADBLOCK_ERASEERROR = 1, // Error on erase
LFS_EMUBD_BADBLOCK_READERROR = 2, // Error on read
LFS_EMUBD_BADBLOCK_PROGNOOP = 3, // Prog does nothing silently
LFS_EMUBD_BADBLOCK_ERASENOOP = 4, // Erase does nothing silently
LFS_EMUBD_BADBLOCK_PROGFLIP = 5, // Prog flips a bit
LFS_EMUBD_BADBLOCK_READFLIP = 6, // Read flips a bit sometimes
LFS_EMUBD_BADBLOCK_MANUAL = 7, // Bits require manual flipping
} lfs_emubd_badblock_behavior_t;
// Mode determining how power-loss behaves during testing.
typedef enum lfs_emubd_powerloss_behavior {
LFS_EMUBD_POWERLOSS_ATOMIC = 0, // Progs are atomic
LFS_EMUBD_POWERLOSS_SOMEBITS = 1, // One bit is progged
LFS_EMUBD_POWERLOSS_MOSTBITS = 2, // All-but-one bit is progged
LFS_EMUBD_POWERLOSS_OOO = 3, // Blocks are written out-of-order
LFS_EMUBD_POWERLOSS_METASTABLE = 4, // Reads may flip a bit
} lfs_emubd_powerloss_behavior_t;
// Type for measuring read/program/erase operations
typedef uint64_t lfs_emubd_io_t;
typedef int64_t lfs_emubd_sio_t;
// Type for measuring wear
typedef uint32_t lfs_emubd_wear_t;
typedef int32_t lfs_emubd_swear_t;
// Type for tracking power-cycles
typedef uint32_t lfs_emubd_powercycles_t;
typedef int32_t lfs_emubd_spowercycles_t;
// Type for delays in nanoseconds
typedef uint64_t lfs_emubd_sleep_t;
typedef int64_t lfs_emubd_ssleep_t;
// emubd config, this is required for testing
struct lfs_emubd_config {
// 8-bit erase value to use for simulating erases. -1 simulates a noop
// erase, which is faster than simulating a fixed erase value.
int32_t erase_value;
// Number of erase cycles before a block becomes "bad". The exact behavior
// of bad blocks is controlled by badblock_behavior.
uint32_t erase_cycles;
// The mode determining how bad-blocks fail
lfs_emubd_badblock_behavior_t badblock_behavior;
// Number of write operations (erase/prog) before triggering a power-loss.
// power_cycles=0 disables this. The exact behavior of power-loss is
// controlled by a combination of powerloss_behavior and powerloss_cb.
lfs_emubd_powercycles_t power_cycles;
// The mode determining how power-loss affects disk
lfs_emubd_powerloss_behavior_t powerloss_behavior;
// Function to call to emulate power-loss. The exact behavior of power-loss
// is up to the runner to provide.
void (*powerloss_cb)(void*);
// Data for power-loss callback
void *powerloss_data;
// Seed for prng, which may be used for emulating failed progs. This does
// not affect normal operation.
uint32_t seed;
// Path to file to use as a mirror of the disk. This provides a way to view
// the current state of the block device.
const char *disk_path;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs_emubd_sleep_t read_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs_emubd_sleep_t prog_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs_emubd_sleep_t erase_sleep;
};
// A reference counted block
typedef struct lfs_emubd_block {
uint32_t rc;
lfs_emubd_wear_t wear;
bool metastable;
// sign(bad_bit)=0 => randomized on erase
// sign(bad_bit)=1 => fixed
lfs_size_t bad_bit;
uint8_t data[];
} lfs_emubd_block_t;
// Disk mirror
typedef struct lfs_emubd_disk {
uint32_t rc;
int fd;
uint8_t *scratch;
} lfs_emubd_disk_t;
// emubd state
typedef struct lfs_emubd {
// array of copy-on-write blocks
lfs_emubd_block_t **blocks;
// some other test state
lfs_emubd_io_t readed;
lfs_emubd_io_t proged;
lfs_emubd_io_t erased;
uint32_t prng;
lfs_emubd_powercycles_t power_cycles;
lfs_emubd_block_t **ooo_before;
lfs_emubd_block_t **ooo_after;
lfs_emubd_disk_t *disk;
const struct lfs_emubd_config *cfg;
} lfs_emubd_t;
/// Block device API ///
// Create an emulating block device using the geometry in lfs_config
//
// Note that filebd is used if a path is provided, if path is NULL
// emubd will use rambd which can be much faster.
int lfs_emubd_create(const struct lfs_config *cfg, const char *path);
int lfs_emubd_createcfg(const struct lfs_config *cfg, const char *path,
const struct lfs_emubd_config *bdcfg);
// Clean up memory associated with block device
int lfs_emubd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs_emubd_sync(const struct lfs_config *cfg);
/// Additional extended API for driving test features ///
// Set the current prng state
void lfs_emubd_seed(const struct lfs_config *cfg, uint32_t seed);
// Get a pseudo-random number from emubd's internal prng
uint32_t lfs_emubd_prng(const struct lfs_config *cfg);
// Get total amount of bytes read
lfs_emubd_sio_t lfs_emubd_readed(const struct lfs_config *cfg);
// Get total amount of bytes programmed
lfs_emubd_sio_t lfs_emubd_proged(const struct lfs_config *cfg);
// Get total amount of bytes erased
lfs_emubd_sio_t lfs_emubd_erased(const struct lfs_config *cfg);
// Manually set amount of bytes read
int lfs_emubd_setreaded(const struct lfs_config *cfg, lfs_emubd_io_t readed);
// Manually set amount of bytes programmed
int lfs_emubd_setproged(const struct lfs_config *cfg, lfs_emubd_io_t proged);
// Manually set amount of bytes erased
int lfs_emubd_seterased(const struct lfs_config *cfg, lfs_emubd_io_t erased);
// Get simulated wear on a given block
lfs_emubd_swear_t lfs_emubd_wear(const struct lfs_config *cfg,
lfs_block_t block);
// Manually set simulated wear on a given block
int lfs_emubd_setwear(const struct lfs_config *cfg,
lfs_block_t block, lfs_emubd_wear_t wear);
// Mark a block as bad, this is equivalent to setting wear to maximum
int lfs_emubd_markbad(const struct lfs_config *cfg, lfs_block_t block);
// Clear any simulated wear on a given block
int lfs_emubd_markgood(const struct lfs_config *cfg, lfs_block_t block);
// Get which bit failed, this changes on erase/power-loss unless manually set
lfs_ssize_t lfs_emubd_badbit(const struct lfs_config *cfg,
lfs_block_t block);
// Set which bit should fail in a given block
int lfs_emubd_setbadbit(const struct lfs_config *cfg,
lfs_block_t block, lfs_size_t bit);
// Randomize the bad bit on erase (the default)
int lfs_emubd_randomizebadbit(const struct lfs_config *cfg,
lfs_block_t block);
// Mark a block as bad and which bit should fail
int lfs_emubd_markbadbit(const struct lfs_config *cfg,
lfs_block_t block, lfs_size_t bit);
// Flip a bit in a given block, intended for emulating bit errors
int lfs_emubd_flipbit(const struct lfs_config *cfg,
lfs_block_t block, lfs_size_t bit);
// Flip all bits marked as bad
int lfs_emubd_flip(const struct lfs_config *cfg);
// Get the remaining power-cycles
lfs_emubd_spowercycles_t lfs_emubd_powercycles(
const struct lfs_config *cfg);
// Manually set the remaining power-cycles
int lfs_emubd_setpowercycles(const struct lfs_config *cfg,
lfs_emubd_powercycles_t power_cycles);
// Create a copy-on-write copy of the state of this block device
int lfs_emubd_cpy(const struct lfs_config *cfg, lfs_emubd_t *copy);
#endif
-56
View File
@@ -1,56 +0,0 @@
/*
* Block device emulated in a file
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_FILEBD_H
#define LFS_FILEBD_H
#include "lfs.h"
#include "lfs_util.h"
// Block device specific tracing
#ifndef LFS_FILEBD_TRACE
#ifdef LFS_FILEBD_YES_TRACE
#define LFS_FILEBD_TRACE(...) LFS_TRACE(__VA_ARGS__)
#else
#define LFS_FILEBD_TRACE(...)
#endif
#endif
// filebd state
typedef struct lfs_filebd {
int fd;
} lfs_filebd_t;
// Create a file block device using the geometry in lfs_config
int lfs_filebd_create(const struct lfs_config *cfg, const char *path);
// Clean up memory associated with block device
int lfs_filebd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs_filebd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs_filebd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs_filebd_sync(const struct lfs_config *cfg);
#endif
-131
View File
@@ -1,131 +0,0 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "bd/lfs_rambd.h"
int lfs_rambd_createcfg(const struct lfs_config *cfg,
const struct lfs_rambd_config *bdcfg) {
LFS_RAMBD_TRACE("lfs_rambd_createcfg(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"}, "
"%p {.buffer=%p})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
(void*)bdcfg, bdcfg->buffer);
lfs_rambd_t *bd = cfg->context;
bd->cfg = bdcfg;
// allocate buffer?
if (bd->cfg->buffer) {
bd->buffer = bd->cfg->buffer;
} else {
bd->buffer = lfs_malloc(cfg->block_size * cfg->block_count);
if (!bd->buffer) {
LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", LFS_ERR_NOMEM);
return LFS_ERR_NOMEM;
}
}
// zero for reproducibility
memset(bd->buffer, 0, cfg->block_size * cfg->block_count);
LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", 0);
return 0;
}
int lfs_rambd_create(const struct lfs_config *cfg) {
LFS_RAMBD_TRACE("lfs_rambd_create(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count);
static const struct lfs_rambd_config defaults = {0};
int err = lfs_rambd_createcfg(cfg, &defaults);
LFS_RAMBD_TRACE("lfs_rambd_create -> %d", err);
return err;
}
int lfs_rambd_destroy(const struct lfs_config *cfg) {
LFS_RAMBD_TRACE("lfs_rambd_destroy(%p)", (void*)cfg);
// clean up memory
lfs_rambd_t *bd = cfg->context;
if (!bd->cfg->buffer) {
lfs_free(bd->buffer);
}
LFS_RAMBD_TRACE("lfs_rambd_destroy -> %d", 0);
return 0;
}
int lfs_rambd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size) {
LFS_RAMBD_TRACE("lfs_rambd_read(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs_rambd_t *bd = cfg->context;
// check if read is valid
LFS_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->read_size == 0);
LFS_ASSERT(size % cfg->read_size == 0);
LFS_ASSERT(off+size <= cfg->block_size);
// read data
memcpy(buffer, &bd->buffer[block*cfg->block_size + off], size);
LFS_RAMBD_TRACE("lfs_rambd_read -> %d", 0);
return 0;
}
int lfs_rambd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size) {
LFS_RAMBD_TRACE("lfs_rambd_prog(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs_rambd_t *bd = cfg->context;
// check if write is valid
LFS_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->prog_size == 0);
LFS_ASSERT(size % cfg->prog_size == 0);
LFS_ASSERT(off+size <= cfg->block_size);
// program data
memcpy(&bd->buffer[block*cfg->block_size + off], buffer, size);
LFS_RAMBD_TRACE("lfs_rambd_prog -> %d", 0);
return 0;
}
int lfs_rambd_erase(const struct lfs_config *cfg, lfs_block_t block) {
LFS_RAMBD_TRACE("lfs_rambd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
(void*)cfg, block, cfg->block_size);
// check if erase is valid
LFS_ASSERT(block < cfg->block_count);
// erase is a noop
(void)block;
LFS_RAMBD_TRACE("lfs_rambd_erase -> %d", 0);
return 0;
}
int lfs_rambd_sync(const struct lfs_config *cfg) {
LFS_RAMBD_TRACE("lfs_rambd_sync(%p)", (void*)cfg);
// sync is a noop
(void)cfg;
LFS_RAMBD_TRACE("lfs_rambd_sync -> %d", 0);
return 0;
}
-65
View File
@@ -1,65 +0,0 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_RAMBD_H
#define LFS_RAMBD_H
#include "lfs.h"
#include "lfs_util.h"
// Block device specific tracing
#ifndef LFS_RAMBD_TRACE
#ifdef LFS_RAMBD_YES_TRACE
#define LFS_RAMBD_TRACE(...) LFS_TRACE(__VA_ARGS__)
#else
#define LFS_RAMBD_TRACE(...)
#endif
#endif
// rambd config (optional)
struct lfs_rambd_config {
// Optional statically allocated buffer for the block device.
void *buffer;
};
// rambd state
typedef struct lfs_rambd {
uint8_t *buffer;
const struct lfs_rambd_config *cfg;
} lfs_rambd_t;
// Create a RAM block device using the geometry in lfs_config
int lfs_rambd_create(const struct lfs_config *cfg);
int lfs_rambd_createcfg(const struct lfs_config *cfg,
const struct lfs_rambd_config *bdcfg);
// Clean up memory associated with block device
int lfs_rambd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs_rambd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs_rambd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs_rambd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs_rambd_sync(const struct lfs_config *cfg);
#endif
+5213 -5209
View File
File diff suppressed because it is too large Load Diff
+426 -419
View File
File diff suppressed because it is too large Load Diff
+43 -43
View File
@@ -1,22 +1,22 @@
/*
* lfs util functions
* lfs3 util functions
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "lfs_util.h"
#include "lfs3_util.h"
// Only compile if user does not provide custom config
#ifndef LFS_CONFIG
#ifndef LFS3_CONFIG
// Need lfs.h for error codes
// TODO should we actually move the error codes to lfs_util.h?
#include "lfs.h"
// Need lfs3.h for error codes
// TODO should we actually move the error codes to lfs3_util.h?
#include "lfs3.h"
// Convert to/from leb128 encoding
ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size) {
ssize_t lfs3_toleb128(uint32_t word, void *buffer, size_t size) {
uint8_t *data = buffer;
for (size_t i = 0; i < size; i++) {
@@ -31,10 +31,10 @@ ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size) {
}
// buffer overflow?
LFS_UNREACHABLE();
LFS3_UNREACHABLE();
}
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
ssize_t lfs3_fromleb128(uint32_t *word, const void *buffer, size_t size) {
const uint8_t *data = buffer;
int32_t word_ = 0;
@@ -44,7 +44,7 @@ ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
if (!(dat & 0x80)) {
// did we overflow?
if ((word_ >> 7*i) != dat) {
return LFS_ERR_CORRUPT;
return LFS3_ERR_CORRUPT;
}
*word = word_;
@@ -53,15 +53,15 @@ ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
}
// truncated?
return LFS_ERR_CORRUPT;
return LFS3_ERR_CORRUPT;
}
// crc32c tables (see lfs_crc32c for more info)
#if !defined(LFS_SMALLER_CRC32C) \
&& !defined(LFS_FASTER_CRC32C) \
&& !defined(LFS_PMUL_CRC32C)
static const uint32_t lfs_crc32c_table[16] = {
// crc32c tables (see lfs3_crc32c for more info)
#if !defined(LFS3_SMALLER_CRC32C) \
&& !defined(LFS3_FASTER_CRC32C) \
&& !defined(LFS3_PMUL_CRC32C)
static const uint32_t lfs3_crc32c_table[16] = {
0x00000000, 0x105ec76f, 0x20bd8ede, 0x30e349b1,
0x417b1dbc, 0x5125dad3, 0x61c69362, 0x7198540d,
0x82f63b78, 0x92a8fc17, 0xa24bb5a6, 0xb21572c9,
@@ -69,10 +69,10 @@ static const uint32_t lfs_crc32c_table[16] = {
};
#endif
#if defined(LFS_FASTER_CRC32C) \
&& !defined(LFS_SMALLER_CRC32C) \
&& !defined(LFS_PMUL_CRC32C)
static const uint32_t lfs_crc32c_table[256] = {
#if defined(LFS3_FASTER_CRC32C) \
&& !defined(LFS3_SMALLER_CRC32C) \
&& !defined(LFS3_PMUL_CRC32C)
static const uint32_t lfs3_crc32c_table[256] = {
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
@@ -142,7 +142,7 @@ static const uint32_t lfs_crc32c_table[256] = {
// Calculate crc32c incrementally
uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
uint32_t lfs3_crc32c(uint32_t crc, const void *buffer, size_t size) {
// init with 0xffffffff so prefixed zeros affect the crc
const uint8_t *buffer_ = buffer;
crc ^= 0xffffffff;
@@ -179,7 +179,7 @@ uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
// PCLMULQDQ Instruction whitepaper is an excellent resource on this
// topic.
//
#if defined(LFS_SMALLER_CRC32C) && !defined(LFS_PMUL_CRC32C)
#if defined(LFS3_SMALLER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// naive reduce
for (size_t i = 0; i < size; i++) {
crc = crc ^ buffer_[i];
@@ -188,36 +188,36 @@ uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
}
}
#elif !defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C)
#elif !defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via small table
for (size_t i = 0; i < size; i++) {
crc = (crc >> 4) ^ lfs_crc32c_table[0xf & (crc ^ (buffer_[i] >> 0))];
crc = (crc >> 4) ^ lfs_crc32c_table[0xf & (crc ^ (buffer_[i] >> 4))];
crc = (crc >> 4) ^ lfs3_crc32c_table[0xf & (crc ^ (buffer_[i] >> 0))];
crc = (crc >> 4) ^ lfs3_crc32c_table[0xf & (crc ^ (buffer_[i] >> 4))];
}
#elif defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C)
#elif defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via big table
for (size_t i = 0; i < size; i++) {
crc = (crc >> 8) ^ lfs_crc32c_table[0xff & (crc ^ buffer_[i])];
crc = (crc >> 8) ^ lfs3_crc32c_table[0xff & (crc ^ buffer_[i])];
}
#elif defined(LFS_PMUL_CRC32C)
#elif defined(LFS3_PMUL_CRC32C)
// reduce via Barret reduction
for (size_t i = 0; i < size;) {
// align to 32-bits
if ((uintptr_t)&buffer_[i] % sizeof(uint32_t) == 0
&& i+sizeof(uint32_t) < size) {
crc = crc ^ lfs_fromle32_(&buffer_[i]);
crc = lfs_pmul(
lfs_pmul(crc, 0xdea713f1),
crc = crc ^ lfs3_fromle32_(&buffer_[i]);
crc = lfs3_pmul(
lfs3_pmul(crc, 0xdea713f1),
0x82f63b78)
>> 31;
i += 4;
} else {
crc = crc ^ buffer_[i];
crc = (crc >> 8)
^ (lfs_pmul(
lfs_pmul(crc << 24, 0xdea713f1),
^ (lfs3_pmul(
lfs3_pmul(crc << 24, 0xdea713f1),
0x82f63b78)
>> 31);
i += 1;
@@ -232,7 +232,7 @@ uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
}
// Multiply two crc32cs in the crc32c ring
uint32_t lfs_crc32c_mul(uint32_t a, uint32_t b) {
uint32_t lfs3_crc32c_mul(uint32_t a, uint32_t b) {
// Multiplication in a crc32c ring involves polynomial
// multiplication modulo the crc32c polynomial to keep things
// finite:
@@ -247,33 +247,33 @@ uint32_t lfs_crc32c_mul(uint32_t a, uint32_t b) {
// This gets a bit funky because crc32cs are little-endian, but
// fortunately pmul is symmetric. Though the result is awkwardly
// 63-bits, so we need to shift by 1.
uint64_t r = lfs_pmul(a, b) << 1;
uint64_t r = lfs3_pmul(a, b) << 1;
// We can accelerate our module with crc32c tables if present, these
// loops may look familiar.
#if defined(LFS_SMALLER_CRC32C) && !defined(LFS_PMUL_CRC32C)
#if defined(LFS3_SMALLER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// naive reduce
for (int i = 0; i < 32; i++) {
r = (r >> 1) ^ ((r & 1) ? 0x82f63b78 : 0);
}
#elif !defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C)
#elif !defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via small table
for (int i = 0; i < 8; i++) {
r = (r >> 4) ^ lfs_crc32c_table[0xf & r];
r = (r >> 4) ^ lfs3_crc32c_table[0xf & r];
}
#elif defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C)
#elif defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via big table
for (int i = 0; i < 4; i++) {
r = (r >> 8) ^ lfs_crc32c_table[0xff & r];
r = (r >> 8) ^ lfs3_crc32c_table[0xff & r];
}
#elif defined(LFS_PMUL_CRC32C)
#elif defined(LFS3_PMUL_CRC32C)
// reduce via Barret reduction
r = (r >> 32)
^ (lfs_pmul(
lfs_pmul(r, 0xdea713f1),
^ (lfs3_pmul(
lfs3_pmul(r, 0xdea713f1),
0x82f63b78)
>> 31);
#endif
+211 -211
View File
@@ -1,93 +1,93 @@
/*
* lfs utility functions
* lfs3 utility functions
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_UTIL_H
#define LFS_UTIL_H
#ifndef LFS3_UTIL_H
#define LFS3_UTIL_H
// Users can override lfs_util.h with their own configuration by defining
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
// Users can override lfs3_util.h with their own configuration by defining
// LFS3_CONFIG as a header file to include (-DLFS_CONFIG=lfs3_config.h).
//
// If LFS_CONFIG is used, none of the default utils will be emitted and must be
// provided by the config file. To start, I would suggest copying lfs_util.h
// If LFS3_CONFIG is used, none of the default utils will be emitted and must be
// provided by the config file. To start, I would suggest copying lfs3_util.h
// and modifying as needed.
#ifdef LFS_CONFIG
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
#define LFS_STRINGIZE2(x) #x
#include LFS_STRINGIZE(LFS_CONFIG)
#ifdef LFS3_CONFIG
#define LFS3_STRINGIZE(x) LFS3_STRINGIZE2(x)
#define LFS3_STRINGIZE2(x) #x
#include LFS3_STRINGIZE(LFS3_CONFIG)
#else
// Some convenient macro aliases
// TODO move these to something like lfs_cfg.h?
// TODO move these to something like lfs3_cfg.h?
// LFS_BIGGEST enables all opt-in features
#ifdef LFS_BIGGEST
#ifndef LFS_REVDBG
#define LFS_REVDBG
// LFS3_BIGGEST enables all opt-in features
#ifdef LFS3_BIGGEST
#ifndef LFS3_REVDBG
#define LFS3_REVDBG
#endif
#ifndef LFS_REVNOISE
#define LFS_REVNOISE
#ifndef LFS3_REVNOISE
#define LFS3_REVNOISE
#endif
#ifndef LFS_CKPROGS
#define LFS_CKPROGS
#ifndef LFS3_CKPROGS
#define LFS3_CKPROGS
#endif
#ifndef LFS_CKFETCHES
#define LFS_CKFETCHES
#ifndef LFS3_CKFETCHES
#define LFS3_CKFETCHES
#endif
#ifndef LFS_CKMETAPARITY
#define LFS_CKMETAPARITY
#ifndef LFS3_CKMETAPARITY
#define LFS3_CKMETAPARITY
#endif
#ifndef LFS_CKDATACKSUMREADS
#define LFS_CKDATACKSUMREADS
#ifndef LFS3_CKDATACKSUMREADS
#define LFS3_CKDATACKSUMREADS
#endif
#ifndef LFS_GC
#define LFS_GC
#ifndef LFS3_GC
#define LFS3_GC
#endif
#endif
// LFS_YES_* variants imply the relevant LFS_* macro
#ifdef LFS_YES_RDONLY
#define LFS_RDONLY
// LFS3_YES_* variants imply the relevant LFS3_* macro
#ifdef LFS3_YES_RDONLY
#define LFS3_RDONLY
#endif
#ifdef LFS_YES_REVDBG
#define LFS_REVDBG
#ifdef LFS3_YES_REVDBG
#define LFS3_REVDBG
#endif
#ifdef LFS_YES_REVNOISE
#define LFS_REVNOISE
#ifdef LFS3_YES_REVNOISE
#define LFS3_REVNOISE
#endif
#ifdef LFS_YES_CKPROGS
#define LFS_CKPROGS
#ifdef LFS3_YES_CKPROGS
#define LFS3_CKPROGS
#endif
#ifdef LFS_YES_CKFETCHES
#define LFS_CKFETCHES
#ifdef LFS3_YES_CKFETCHES
#define LFS3_CKFETCHES
#endif
#ifdef LFS_YES_CKMETAPARITY
#define LFS_CKMETAPARITY
#ifdef LFS3_YES_CKMETAPARITY
#define LFS3_CKMETAPARITY
#endif
#ifdef LFS_YES_CKDATACKSUMREADS
#define LFS_CKDATACKSUMREADS
#ifdef LFS3_YES_CKDATACKSUMREADS
#define LFS3_CKDATACKSUMREADS
#endif
#ifdef LFS_YES_GC
#define LFS_GC
#ifdef LFS3_YES_GC
#define LFS3_GC
#endif
// LFS_NO_LOG disables all logging macros
#ifdef LFS_NO_LOG
#ifndef LFS_NO_DEBUG
#define LFS_NO_DEBUG
// LFS3_NO_LOG disables all logging macros
#ifdef LFS3_NO_LOG
#ifndef LFS3_NO_DEBUG
#define LFS3_NO_DEBUG
#endif
#ifndef LFS_NO_INFO
#define LFS_NO_INFO
#ifndef LFS3_NO_INFO
#define LFS3_NO_INFO
#endif
#ifndef LFS_NO_WARN
#define LFS_NO_WARN
#ifndef LFS3_NO_WARN
#define LFS3_NO_WARN
#endif
#ifndef LFS_NO_ERROR
#define LFS_NO_ERROR
#ifndef LFS3_NO_ERROR
#define LFS3_NO_ERROR
#endif
#endif
@@ -97,20 +97,20 @@
#include <stdbool.h>
#include <sys/types.h>
#include <inttypes.h>
#ifndef LFS_NO_STRINGH
#ifndef LFS3_NO_STRINGH
#include <string.h>
#endif
#ifndef LFS_NO_MALLOC
#ifndef LFS3_NO_MALLOC
#include <stdlib.h>
#endif
#ifndef LFS_NO_ASSERT
#ifndef LFS3_NO_ASSERT
#include <assert.h>
#endif
#if !defined(LFS_NO_DEBUG) || \
!defined(LFS_NO_INFO) || \
!defined(LFS_NO_WARN) || \
!defined(LFS_NO_ERROR) || \
defined(LFS_YES_TRACE)
#if !defined(LFS3_NO_DEBUG) || \
!defined(LFS3_NO_INFO) || \
!defined(LFS3_NO_WARN) || \
!defined(LFS3_NO_ERROR) || \
defined(LFS3_YES_TRACE)
#include <stdio.h>
#endif
@@ -120,139 +120,139 @@
// code footprint
// Logging functions
#ifndef LFS_TRACE
#ifdef LFS_YES_TRACE
#define LFS_TRACE_(fmt, ...) \
#ifndef LFS3_TRACE
#ifdef LFS3_YES_TRACE
#define LFS3_TRACE_(fmt, ...) \
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
#define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
#else
#define LFS_TRACE(...)
#define LFS3_TRACE(...)
#endif
#endif
#ifndef LFS_DEBUG
#ifndef LFS_NO_DEBUG
#define LFS_DEBUG_(fmt, ...) \
#ifndef LFS3_DEBUG
#ifndef LFS3_NO_DEBUG
#define LFS3_DEBUG_(fmt, ...) \
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "")
#define LFS3_DEBUG(...) LFS3_DEBUG_(__VA_ARGS__, "")
#else
#define LFS_DEBUG(...)
#define LFS3_DEBUG(...)
#endif
#endif
#ifndef LFS_INFO
#ifndef LFS_NO_INFO
#define LFS_INFO_(fmt, ...) \
#ifndef LFS3_INFO
#ifndef LFS3_NO_INFO
#define LFS3_INFO_(fmt, ...) \
printf("%s:%d:info: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_INFO(...) LFS_INFO_(__VA_ARGS__, "")
#define LFS3_INFO(...) LFS3_INFO_(__VA_ARGS__, "")
#else
#define LFS_INFO(...)
#define LFS3_INFO(...)
#endif
#endif
#ifndef LFS_WARN
#ifndef LFS_NO_WARN
#define LFS_WARN_(fmt, ...) \
#ifndef LFS3_WARN
#ifndef LFS3_NO_WARN
#define LFS3_WARN_(fmt, ...) \
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "")
#define LFS3_WARN(...) LFS3_WARN_(__VA_ARGS__, "")
#else
#define LFS_WARN(...)
#define LFS3_WARN(...)
#endif
#endif
#ifndef LFS_ERROR
#ifndef LFS_NO_ERROR
#define LFS_ERROR_(fmt, ...) \
#ifndef LFS3_ERROR
#ifndef LFS3_NO_ERROR
#define LFS3_ERROR_(fmt, ...) \
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "")
#define LFS3_ERROR(...) LFS3_ERROR_(__VA_ARGS__, "")
#else
#define LFS_ERROR(...)
#define LFS3_ERROR(...)
#endif
#endif
// Runtime assertions
#ifndef LFS_ASSERT
#ifndef LFS_NO_ASSERT
#define LFS_ASSERT(test) assert(test)
#ifndef LFS3_ASSERT
#ifndef LFS3_NO_ASSERT
#define LFS3_ASSERT(test) assert(test)
#else
#define LFS_ASSERT(test)
#define LFS3_ASSERT(test)
#endif
#endif
#ifndef LFS_UNREACHABLE
#ifndef LFS_NO_ASSERT
#define LFS_UNREACHABLE() LFS_ASSERT(false)
#elif !defined(LFS_NO_BUILTINS)
#define LFS_UNREACHABLE() __builtin_unreachable()
#ifndef LFS3_UNREACHABLE
#ifndef LFS3_NO_ASSERT
#define LFS3_UNREACHABLE() LFS3_ASSERT(false)
#elif !defined(LFS3_NO_BUILTINS)
#define LFS3_UNREACHABLE() __builtin_unreachable()
#else
#define LFS_UNREACHABLE()
#define LFS3_UNREACHABLE()
#endif
#endif
// Some ifdef conveniences
#ifdef LFS_REVDBG
#define LFS_IFDEF_REVDBG(a, b) (a)
#ifdef LFS3_REVDBG
#define LFS3_IFDEF_REVDBG(a, b) (a)
#else
#define LFS_IFDEF_REVDBG(a, b) (b)
#define LFS3_IFDEF_REVDBG(a, b) (b)
#endif
#ifdef LFS_REVNOISE
#define LFS_IFDEF_REVNOISE(a, b) (a)
#ifdef LFS3_REVNOISE
#define LFS3_IFDEF_REVNOISE(a, b) (a)
#else
#define LFS_IFDEF_REVNOISE(a, b) (b)
#define LFS3_IFDEF_REVNOISE(a, b) (b)
#endif
#ifdef LFS_CKPROGS
#define LFS_IFDEF_CKPROGS(a, b) (a)
#ifdef LFS3_CKPROGS
#define LFS3_IFDEF_CKPROGS(a, b) (a)
#else
#define LFS_IFDEF_CKPROGS(a, b) (b)
#define LFS3_IFDEF_CKPROGS(a, b) (b)
#endif
#ifdef LFS_CKFETCHES
#define LFS_IFDEF_CKFETCHES(a, b) (a)
#ifdef LFS3_CKFETCHES
#define LFS3_IFDEF_CKFETCHES(a, b) (a)
#else
#define LFS_IFDEF_CKFETCHES(a, b) (b)
#define LFS3_IFDEF_CKFETCHES(a, b) (b)
#endif
#ifdef LFS_CKMETAPARITY
#define LFS_IFDEF_CKMETAPARITY(a, b) (a)
#ifdef LFS3_CKMETAPARITY
#define LFS3_IFDEF_CKMETAPARITY(a, b) (a)
#else
#define LFS_IFDEF_CKMETAPARITY(a, b) (b)
#define LFS3_IFDEF_CKMETAPARITY(a, b) (b)
#endif
#ifdef LFS_CKDATACKSUMREADS
#define LFS_IFDEF_CKDATACKSUMREADS(a, b) (a)
#ifdef LFS3_CKDATACKSUMREADS
#define LFS3_IFDEF_CKDATACKSUMREADS(a, b) (a)
#else
#define LFS_IFDEF_CKDATACKSUMREADS(a, b) (b)
#define LFS3_IFDEF_CKDATACKSUMREADS(a, b) (b)
#endif
#ifdef LFS_GC
#define LFS_IFDEF_GC(a, b) (a)
#ifdef LFS3_GC
#define LFS3_IFDEF_GC(a, b) (a)
#else
#define LFS_IFDEF_GC(a, b) (b)
#define LFS3_IFDEF_GC(a, b) (b)
#endif
// Some function attributes, no way around these
// Force a function to be inlined
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
#define LFS_FORCEINLINE __attribute__((always_inline))
#if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
#define LFS3_FORCEINLINE __attribute__((always_inline))
#else
#define LFS_FORCEINLINE
#define LFS3_FORCEINLINE
#endif
// Force a function to _not_ be inlined
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
#define LFS_NOINLINE __attribute__((noinline))
#if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
#define LFS3_NOINLINE __attribute__((noinline))
#else
#define LFS_NOINLINE
#define LFS3_NOINLINE
#endif
// Builtin functions, these may be replaced by more efficient
// toolchain-specific implementations. LFS_NO_BUILTINS falls back to a more
// toolchain-specific implementations. LFS3_NO_BUILTINS falls back to a more
// expensive basic C implementation for debugging purposes
//
// Most of the backup implementations are based on the infamous Bit
@@ -261,33 +261,33 @@
//
// Compile time min/max
#define LFS_MIN(a, b) ((a < b) ? a : b)
#define LFS_MAX(a, b) ((a > b) ? a : b)
#define LFS3_MIN(a, b) ((a < b) ? a : b)
#define LFS3_MAX(a, b) ((a > b) ? a : b)
// Min/max functions for unsigned 32-bit numbers
static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
static inline uint32_t lfs3_min(uint32_t a, uint32_t b) {
return (a < b) ? a : b;
}
static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
static inline uint32_t lfs3_max(uint32_t a, uint32_t b) {
return (a > b) ? a : b;
}
static inline int32_t lfs_smin(int32_t a, int32_t b) {
static inline int32_t lfs3_smin(int32_t a, int32_t b) {
return (a < b) ? a : b;
}
static inline int32_t lfs_smax(int32_t a, int32_t b) {
static inline int32_t lfs3_smax(int32_t a, int32_t b) {
return (a > b) ? a : b;
}
// Absolute value of signed numbers
static inline int32_t lfs_abs(int32_t a) {
static inline int32_t lfs3_abs(int32_t a) {
return (a < 0) ? -a : a;
}
// Swap two variables
#define LFS_SWAP(_t, _a, _b) \
#define LFS3_SWAP(_t, _a, _b) \
do { \
_t *a = _a; \
_t *b = _b; \
@@ -297,22 +297,22 @@ static inline int32_t lfs_abs(int32_t a) {
} while (0)
// Align to nearest multiple of a size
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
static inline uint32_t lfs3_aligndown(uint32_t a, uint32_t alignment) {
return a - (a % alignment);
}
static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) {
return lfs_aligndown(a + alignment-1, alignment);
static inline uint32_t lfs3_alignup(uint32_t a, uint32_t alignment) {
return lfs3_aligndown(a + alignment-1, alignment);
}
// Find the smallest power of 2 greater than or equal to a
static inline uint32_t lfs_nlog2(uint32_t a) {
static inline uint32_t lfs3_nlog2(uint32_t a) {
// __builtin_clz of zero is undefined, so treat both 0 and 1 specially
if (a <= 1) {
return a;
}
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
#if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return 32 - __builtin_clz(a-1);
#else
uint32_t r = 0;
@@ -327,18 +327,18 @@ static inline uint32_t lfs_nlog2(uint32_t a) {
}
// Count the number of trailing binary zeros in a
// lfs_ctz(0) may be undefined
static inline uint32_t lfs_ctz(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
// lfs3_ctz(0) may be undefined
static inline uint32_t lfs3_ctz(uint32_t a) {
#if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
return __builtin_ctz(a);
#else
return lfs_nlog2((a & -a) + 1) - 1;
return lfs3_nlog2((a & -a) + 1) - 1;
#endif
}
// Count the number of binary ones in a
static inline uint32_t lfs_popc(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
static inline uint32_t lfs3_popc(uint32_t a) {
#if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return __builtin_popcount(a);
#else
a = a - ((a >> 1) & 0x55555555);
@@ -349,8 +349,8 @@ static inline uint32_t lfs_popc(uint32_t a) {
}
// Returns true if there is an odd number of binary ones in a
static inline bool lfs_parity(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
static inline bool lfs3_parity(uint32_t a) {
#if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return __builtin_parity(a);
#else
a ^= a >> 16;
@@ -362,7 +362,7 @@ static inline bool lfs_parity(uint32_t a) {
// Find the sequence comparison of a and b, this is the distance
// between a and b ignoring overflow
static inline int lfs_scmp(uint32_t a, uint32_t b) {
static inline int lfs3_scmp(uint32_t a, uint32_t b) {
return (int)(unsigned)(a - b);
}
@@ -371,7 +371,7 @@ static inline int lfs_scmp(uint32_t a, uint32_t b) {
// This is a multiply where all adds are replaced with xors. If we view
// a and b as binary polynomials, xor is polynomial addition and pmul is
// polynomial multiplication.
static inline uint64_t lfs_pmul(uint32_t a, uint32_t b) {
static inline uint64_t lfs3_pmul(uint32_t a, uint32_t b) {
uint64_t r = 0;
uint64_t a_ = a;
while (b) {
@@ -386,14 +386,14 @@ static inline uint64_t lfs_pmul(uint32_t a, uint32_t b) {
// Convert to/from 32-bit little-endian
static inline void lfs_tole32(uint32_t word, void *buffer) {
static inline void lfs3_tole32(uint32_t word, void *buffer) {
((uint8_t*)buffer)[0] = word >> 0;
((uint8_t*)buffer)[1] = word >> 8;
((uint8_t*)buffer)[2] = word >> 16;
((uint8_t*)buffer)[3] = word >> 24;
}
static inline uint32_t lfs_fromle32(const void *buffer) {
static inline uint32_t lfs3_fromle32(const void *buffer) {
return (((uint8_t*)buffer)[0] << 0)
| (((uint8_t*)buffer)[1] << 8)
| (((uint8_t*)buffer)[2] << 16)
@@ -401,19 +401,19 @@ static inline uint32_t lfs_fromle32(const void *buffer) {
}
// Convert to/from leb128 encoding
// TODO should we really be using ssize_t here and not lfs_ssize_t?
ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size);
// TODO should we really be using ssize_t here and not lfs3_ssize_t?
ssize_t lfs3_toleb128(uint32_t word, void *buffer, size_t size);
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size);
ssize_t lfs3_fromleb128(uint32_t *word, const void *buffer, size_t size);
// Compare n bytes of memory
#if !defined(LFS_NO_STRINGH)
#define lfs_memcmp memcmp
#elif !defined(LFS_NO_BUILTINS)
#define lfs_memcmp __builtin_memcmp
#if !defined(LFS3_NO_STRINGH)
#define lfs3_memcmp memcmp
#elif !defined(LFS3_NO_BUILTINS)
#define lfs3_memcmp __builtin_memcmp
#else
static inline int lfs_memcmp(const void *a, const void *b, size_t size) {
static inline int lfs3_memcmp(const void *a, const void *b, size_t size) {
const uint8_t *a_ = a;
const uint8_t *b_ = b;
for (size_t i = 0; i < size; i++) {
@@ -427,12 +427,12 @@ static inline int lfs_memcmp(const void *a, const void *b, size_t size) {
#endif
// Copy n bytes from src to dst, src and dst must not overlap
#if !defined(LFS_NO_STRINGH)
#define lfs_memcpy memcpy
#elif !defined(LFS_NO_BUILTINS)
#define lfs_memcpy __builtin_memcpy
#if !defined(LFS3_NO_STRINGH)
#define lfs3_memcpy memcpy
#elif !defined(LFS3_NO_BUILTINS)
#define lfs3_memcpy __builtin_memcpy
#else
static inline void *lfs_memcpy(
static inline void *lfs3_memcpy(
void *restrict dst, const void *restrict src, size_t size) {
uint8_t *dst_ = dst;
const uint8_t *src_ = src;
@@ -445,12 +445,12 @@ static inline void *lfs_memcpy(
#endif
// Copy n bytes from src to dst, src and dst may overlap
#if !defined(LFS_NO_STRINGH)
#define lfs_memmove memmove
#elif !defined(LFS_NO_BUILTINS)
#define lfs_memmove __builtin_memmove
#if !defined(LFS3_NO_STRINGH)
#define lfs3_memmove memmove
#elif !defined(LFS3_NO_BUILTINS)
#define lfs3_memmove __builtin_memmove
#else
static inline void *lfs_memmove(void *dst, const void *src, size_t size) {
static inline void *lfs3_memmove(void *dst, const void *src, size_t size) {
uint8_t *dst_ = dst;
const uint8_t *src_ = src;
if (dst_ < src_) {
@@ -468,12 +468,12 @@ static inline void *lfs_memmove(void *dst, const void *src, size_t size) {
#endif
// Set n bytes to c
#if !defined(LFS_NO_STRINGH)
#define lfs_memset memset
#elif !defined(LFS_NO_BUILTINS)
#define lfs_memset __builtin_memset
#if !defined(LFS3_NO_STRINGH)
#define lfs3_memset memset
#elif !defined(LFS3_NO_BUILTINS)
#define lfs3_memset __builtin_memset
#else
static inline void *lfs_memset(void *dst, int c, size_t size) {
static inline void *lfs3_memset(void *dst, int c, size_t size) {
uint8_t *dst_ = dst;
for (size_t i = 0; i < size; i++) {
dst_[i] = c;
@@ -484,10 +484,10 @@ static inline void *lfs_memset(void *dst, int c, size_t size) {
#endif
// Find the first occurrence of c or NULL
#if !defined(LFS_NO_STRINGH)
#define lfs_memchr memchr
#if !defined(LFS3_NO_STRINGH)
#define lfs3_memchr memchr
#else
static inline void *lfs_memchr(const void *a, int c, size_t size) {
static inline void *lfs3_memchr(const void *a, int c, size_t size) {
const uint8_t *a_ = a;
for (size_t i = 0; i < size; i++) {
if (a_[i] == c) {
@@ -500,7 +500,7 @@ static inline void *lfs_memchr(const void *a, int c, size_t size) {
#endif
// Find the first occurrence of anything not c or NULL
static inline void *lfs_memcchr(const void *a, int c, size_t size) {
static inline void *lfs3_memcchr(const void *a, int c, size_t size) {
const uint8_t *a_ = a;
for (size_t i = 0; i < size; i++) {
if (a_[i] != c) {
@@ -512,7 +512,7 @@ static inline void *lfs_memcchr(const void *a, int c, size_t size) {
}
// Find the minimum length that includes all non-zero bytes
static inline size_t lfs_memlen(const void *a, size_t size) {
static inline size_t lfs3_memlen(const void *a, size_t size) {
const uint8_t *a_ = a;
while (size > 0 && a_[size-1] == 0) {
size -= 1;
@@ -522,7 +522,7 @@ static inline size_t lfs_memlen(const void *a, size_t size) {
}
// Xor n bytes from b into a
static inline void *lfs_memxor(
static inline void *lfs3_memxor(
void *restrict a, const void *restrict b, size_t size) {
uint8_t *a_ = a;
const uint8_t *b_ = b;
@@ -535,10 +535,10 @@ static inline void *lfs_memxor(
// Find the length of a null-terminated string
#if !defined(LFS_NO_STRINGH)
#define lfs_strlen strlen
#if !defined(LFS3_NO_STRINGH)
#define lfs3_strlen strlen
#else
static inline size_t lfs_strlen(const char *a) {
static inline size_t lfs3_strlen(const char *a) {
const char *a_ = a;
while (*a_) {
a_++;
@@ -549,10 +549,10 @@ static inline size_t lfs_strlen(const char *a) {
#endif
// Compare two null-terminated strings
#if !defined(LFS_NO_STRINGH)
#define lfs_strcmp strcmp
#if !defined(LFS3_NO_STRINGH)
#define lfs3_strcmp strcmp
#else
static inline int lfs_strcmp(const char *a, const char *b) {
static inline int lfs3_strcmp(const char *a, const char *b) {
while (*a && *a == *b) {
a++;
b++;
@@ -563,10 +563,10 @@ static inline int lfs_strcmp(const char *a, const char *b) {
#endif
// Copy a null-terminated string from src to dst
#if !defined(LFS_NO_STRINGH)
#define lfs_strcpy strcpy
#if !defined(LFS3_NO_STRINGH)
#define lfs3_strcpy strcpy
#else
static inline char *lfs_strcpy(
static inline char *lfs3_strcpy(
char *restrict dst, const char *restrict src) {
char *dst_ = dst;
while (*src) {
@@ -581,10 +581,10 @@ static inline char *lfs_strcpy(
#endif
// Find first occurrence of c or NULL
#ifndef LFS_NO_STRINGH
#define lfs_strchr strchr
#ifndef LFS3_NO_STRINGH
#define lfs3_strchr strchr
#else
static inline char *lfs_strchr(const char *a, int c) {
static inline char *lfs3_strchr(const char *a, int c) {
while (*a) {
if (*a == c) {
return (char*)a;
@@ -598,7 +598,7 @@ static inline char *lfs_strchr(const char *a, int c) {
#endif
// Find first occurrence of anything not c or NULL
static inline char *lfs_strcchr(const char *a, int c) {
static inline char *lfs3_strcchr(const char *a, int c) {
while (*a) {
if (*a != c) {
return (char*)a;
@@ -611,10 +611,10 @@ static inline char *lfs_strcchr(const char *a, int c) {
}
// Find length of a that does not contain any char in cs
#ifndef LFS_NO_STRINGH
#define lfs_strspn strspn
#ifndef LFS3_NO_STRINGH
#define lfs3_strspn strspn
#else
static inline size_t lfs_strspn(const char *a, const char *cs) {
static inline size_t lfs3_strspn(const char *a, const char *cs) {
const char *a_ = a;
while (*a_) {
const char *cs_ = cs;
@@ -633,10 +633,10 @@ static inline size_t lfs_strspn(const char *a, const char *cs) {
#endif
// Find length of a that only contains chars in cs
#ifndef LFS_NO_STRINGH
#define lfs_strcspn strcspn
#ifndef LFS3_NO_STRINGH
#define lfs3_strcspn strcspn
#else
static inline size_t lfs_strcspn(const char *a, const char *cs) {
static inline size_t lfs3_strcspn(const char *a, const char *cs) {
const char *a_ = a;
while (*a_) {
const char *cs_ = cs;
@@ -656,8 +656,8 @@ static inline size_t lfs_strcspn(const char *a, const char *cs) {
// Odd-parity and even-parity zeros in our crc32c ring
#define LFS_CRC32C_ODDZERO 0xfca42daf
#define LFS_CRC32C_EVENZERO 0x00000000
#define LFS3_CRC32C_ODDZERO 0xfca42daf
#define LFS3_CRC32C_EVENZERO 0x00000000
// Calculate crc32c incrementally
//
@@ -665,32 +665,32 @@ static inline size_t lfs_strcspn(const char *a, const char *cs) {
// init = 0xffffffff
// fini = 0xffffffff
//
uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size);
uint32_t lfs3_crc32c(uint32_t crc, const void *buffer, size_t size);
// Multiply two crc32cs in the crc32c ring
uint32_t lfs_crc32c_mul(uint32_t a, uint32_t b);
uint32_t lfs3_crc32c_mul(uint32_t a, uint32_t b);
// Find the cube of a crc32c in the crc32c ring
static inline uint32_t lfs_crc32c_cube(uint32_t a) {
return lfs_crc32c_mul(lfs_crc32c_mul(a, a), a);
static inline uint32_t lfs3_crc32c_cube(uint32_t a) {
return lfs3_crc32c_mul(lfs3_crc32c_mul(a, a), a);
}
// Allocate memory, only used if buffers are not provided to littlefs
#ifndef LFS_NO_MALLOC
#define lfs_malloc malloc
#ifndef LFS3_NO_MALLOC
#define lfs3_malloc malloc
#else
static inline void *lfs_malloc(size_t size) {
static inline void *lfs3_malloc(size_t size) {
(void)size;
return NULL;
}
#endif
// Deallocate memory, only used if buffers are not provided to littlefs
#ifndef LFS_NO_MALLOC
#define lfs_free free
#ifndef LFS3_NO_MALLOC
#define lfs3_free free
#else
static inline void lfs_free(void *p) {
static inline void lfs3_free(void *p) {
(void)p;
}
#endif
+25 -25
View File
@@ -9,7 +9,7 @@
#endif
#include "runners/bench_runner.h"
#include "bd/lfs_emubd.h"
#include "bd/lfs3_emubd.h"
#include <getopt.h>
#include <sys/types.h>
@@ -439,9 +439,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;
lfs_emubd_sleep_t bench_read_sleep = 0.0;
lfs_emubd_sleep_t bench_prog_sleep = 0.0;
lfs_emubd_sleep_t bench_erase_sleep = 0.0;
lfs3_emubd_sleep_t bench_read_sleep = 0.0;
lfs3_emubd_sleep_t bench_prog_sleep = 0.0;
lfs3_emubd_sleep_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
@@ -607,17 +607,17 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size) {
typedef struct bench_record {
const char *m;
uintmax_t n;
lfs_emubd_io_t last_readed;
lfs_emubd_io_t last_proged;
lfs_emubd_io_t last_erased;
lfs3_emubd_io_t last_readed;
lfs3_emubd_io_t last_proged;
lfs3_emubd_io_t last_erased;
} bench_record_t;
static struct lfs_config *bench_cfg = NULL;
static struct lfs3_config *bench_cfg = NULL;
static bench_record_t *bench_records;
size_t bench_record_count;
size_t bench_record_capacity;
void bench_reset(struct lfs_config *cfg) {
void bench_reset(struct lfs3_config *cfg) {
bench_cfg = cfg;
bench_record_count = 0;
}
@@ -625,11 +625,11 @@ void bench_reset(struct lfs_config *cfg) {
void bench_start(const char *m, uintmax_t n) {
// measure current read/prog/erase
assert(bench_cfg);
lfs_emubd_sio_t readed = lfs_emubd_readed(bench_cfg);
lfs3_emubd_sio_t readed = lfs3_emubd_readed(bench_cfg);
assert(readed >= 0);
lfs_emubd_sio_t proged = lfs_emubd_proged(bench_cfg);
lfs3_emubd_sio_t proged = lfs3_emubd_proged(bench_cfg);
assert(proged >= 0);
lfs_emubd_sio_t erased = lfs_emubd_erased(bench_cfg);
lfs3_emubd_sio_t erased = lfs3_emubd_erased(bench_cfg);
assert(erased >= 0);
// allocate a new record
@@ -648,11 +648,11 @@ void bench_start(const char *m, uintmax_t n) {
void bench_stop(const char *m) {
// measure current read/prog/erase
assert(bench_cfg);
lfs_emubd_sio_t readed = lfs_emubd_readed(bench_cfg);
lfs3_emubd_sio_t readed = lfs3_emubd_readed(bench_cfg);
assert(readed >= 0);
lfs_emubd_sio_t proged = lfs_emubd_proged(bench_cfg);
lfs3_emubd_sio_t proged = lfs3_emubd_proged(bench_cfg);
assert(proged >= 0);
lfs_emubd_sio_t erased = lfs_emubd_erased(bench_cfg);
lfs3_emubd_sio_t erased = lfs3_emubd_erased(bench_cfg);
assert(erased >= 0);
// find our record
@@ -1335,18 +1335,18 @@ void perm_run(
}
// create block device and configuration
lfs_emubd_t bd;
lfs3_emubd_t bd;
struct lfs_config cfg = {
struct lfs3_config cfg = {
.context = &bd,
.read = lfs_emubd_read,
.prog = lfs_emubd_prog,
.erase = lfs_emubd_erase,
.sync = lfs_emubd_sync,
.read = lfs3_emubd_read,
.prog = lfs3_emubd_prog,
.erase = lfs3_emubd_erase,
.sync = lfs3_emubd_sync,
BENCH_CFG
};
struct lfs_emubd_config bdcfg = {
struct lfs3_emubd_config bdcfg = {
.disk_path = bench_disk_path,
.read_sleep = bench_read_sleep,
.prog_sleep = bench_prog_sleep,
@@ -1354,7 +1354,7 @@ void perm_run(
BENCH_BDCFG
};
int err = lfs_emubd_createcfg(&cfg, bench_disk_path, &bdcfg);
int err = lfs3_emubd_createcfg(&cfg, bench_disk_path, &bdcfg);
if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1);
@@ -1373,7 +1373,7 @@ void perm_run(
printf("\n");
// cleanup
err = lfs_emubd_destroy(&cfg);
err = lfs3_emubd_destroy(&cfg);
if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1);
@@ -1920,7 +1920,7 @@ getopt_done: ;
if (d >= define_count) {
// align to power of two to avoid any superlinear growth
size_t ncount = 1 << lfs_nlog2(d+1);
size_t ncount = 1 << lfs3_nlog2(d+1);
defines = realloc(defines,
ncount*sizeof(bench_define_t));
memset(defines+define_count, 0,
+13 -13
View File
@@ -8,16 +8,16 @@
#define BENCH_RUNNER_H
// override LFS_TRACE
// override LFS3_TRACE
void bench_trace(const char *fmt, ...);
#define LFS_TRACE_(fmt, ...) \
#define LFS3_TRACE_(fmt, ...) \
bench_trace("%s:%d:trace: " fmt "%s\n", \
__FILE__, \
__LINE__, \
__VA_ARGS__)
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
#define LFS_EMUBD_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
#define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
#define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
// BENCH_START/BENCH_STOP macros measure readed/proged/erased bytes
// through emubd
@@ -36,7 +36,7 @@ void bench_fresult(const char *m, uintmax_t n, double result);
// note these are indirectly included in any generated files
#include "bd/lfs_emubd.h"
#include "bd/lfs3_emubd.h"
#include <stdio.h>
// give source a chance to define feature macros
@@ -45,7 +45,7 @@ void bench_fresult(const char *m, uintmax_t n, double result);
// generated bench configurations
struct lfs_config;
struct lfs3_config;
enum bench_flags {
BENCH_INTERNAL = 0x1,
@@ -69,7 +69,7 @@ struct bench_case {
size_t permutations;
bool (*if_)(void);
void (*run)(struct lfs_config *cfg);
void (*run)(struct lfs3_config *cfg);
};
struct bench_suite {
@@ -110,21 +110,21 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
BENCH_DEFINE(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \
BENCH_DEFINE(DISK_SIZE, 1024*1024 ) \
BENCH_DEFINE(BLOCK_RECYCLES, -1 ) \
BENCH_DEFINE(RCACHE_SIZE, LFS_MAX(16, READ_SIZE) ) \
BENCH_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
BENCH_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) ) \
BENCH_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \
BENCH_DEFINE(FILE_CACHE_SIZE, 16 ) \
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \
BENCH_DEFINE(GC_FLAGS, 0 ) \
BENCH_DEFINE(GC_STEPS, 0 ) \
BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \
BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
BENCH_DEFINE(FRAGMENT_SIZE, LFS_MIN(BLOCK_SIZE/8, 512) ) \
BENCH_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/8, 512) ) \
BENCH_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
BENCH_DEFINE(FRAGMENT_THRESH, -1 ) \
BENCH_DEFINE(ERASE_VALUE, 0xff ) \
BENCH_DEFINE(ERASE_CYCLES, 0 ) \
BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS_EMUBD_BADBLOCK_PROGERROR ) \
BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS_EMUBD_POWERLOSS_ATOMIC ) \
BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) \
BENCH_DEFINE(EMUBD_SEED, 0 )
// declare defines as global intmax_ts
@@ -152,7 +152,7 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
.crystal_thresh = CRYSTAL_THRESH, \
.fragment_thresh = FRAGMENT_THRESH,
#ifdef LFS_GC
#ifdef LFS3_GC
#define BENCH_GC_CFG \
.gc_flags = GC_FLAGS, \
.gc_steps = GC_STEPS,
+76 -76
View File
@@ -9,7 +9,7 @@
#endif
#include "runners/test_runner.h"
#include "bd/lfs_emubd.h"
#include "bd/lfs3_emubd.h"
#include <getopt.h>
#include <sys/types.h>
@@ -117,7 +117,7 @@ typedef struct test_powerloss {
const struct test_powerloss *powerloss,
const struct test_suite *suite,
const struct test_case *case_);
const lfs_emubd_powercycles_t *cycles;
const lfs3_emubd_powercycles_t *cycles;
size_t cycle_count;
} test_powerloss_t;
@@ -450,9 +450,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;
lfs_emubd_sleep_t test_read_sleep = 0.0;
lfs_emubd_sleep_t test_prog_sleep = 0.0;
lfs_emubd_sleep_t test_erase_sleep = 0.0;
lfs3_emubd_sleep_t test_read_sleep = 0.0;
lfs3_emubd_sleep_t test_prog_sleep = 0.0;
lfs3_emubd_sleep_t test_erase_sleep = 0.0;
volatile size_t TEST_PLS = 0;
@@ -623,7 +623,7 @@ 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 lfs_emubd_powercycles_t *cycles,
const lfs3_emubd_powercycles_t *cycles,
size_t cycle_count) {
(void)suite;
// case[:permutation[:powercycles]]
@@ -1299,18 +1299,18 @@ static void run_powerloss_none(
(void)powerloss;
// create block device and configuration
lfs_emubd_t bd;
lfs3_emubd_t bd;
struct lfs_config cfg = {
struct lfs3_config cfg = {
.context = &bd,
.read = lfs_emubd_read,
.prog = lfs_emubd_prog,
.erase = lfs_emubd_erase,
.sync = lfs_emubd_sync,
.read = lfs3_emubd_read,
.prog = lfs3_emubd_prog,
.erase = lfs3_emubd_erase,
.sync = lfs3_emubd_sync,
TEST_CFG
};
struct lfs_emubd_config bdcfg = {
struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path,
.read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep,
@@ -1318,7 +1318,7 @@ static void run_powerloss_none(
TEST_BDCFG
};
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1);
@@ -1339,7 +1339,7 @@ static void run_powerloss_none(
printf("\n");
// cleanup
err = lfs_emubd_destroy(&cfg);
err = lfs3_emubd_destroy(&cfg);
if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1);
@@ -1359,19 +1359,19 @@ static void run_powerloss_linear(
TEST_PLS = 0;
// create block device and configuration
lfs_emubd_t bd;
lfs3_emubd_t bd;
jmp_buf powerloss_jmp;
struct lfs_config cfg = {
struct lfs3_config cfg = {
.context = &bd,
.read = lfs_emubd_read,
.prog = lfs_emubd_prog,
.erase = lfs_emubd_erase,
.sync = lfs_emubd_sync,
.read = lfs3_emubd_read,
.prog = lfs3_emubd_prog,
.erase = lfs3_emubd_erase,
.sync = lfs3_emubd_sync,
TEST_CFG
};
struct lfs_emubd_config bdcfg = {
struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path,
.read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep,
@@ -1384,7 +1384,7 @@ static void run_powerloss_linear(
TEST_BDCFG
};
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1);
@@ -1411,7 +1411,7 @@ static void run_powerloss_linear(
// increment pls
TEST_PLS += 1;
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
? TEST_PLS+1
: 0);
}
@@ -1421,7 +1421,7 @@ static void run_powerloss_linear(
printf("\n");
// cleanup
err = lfs_emubd_destroy(&cfg);
err = lfs3_emubd_destroy(&cfg);
if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1);
@@ -1436,19 +1436,19 @@ static void run_powerloss_log(
TEST_PLS = 0;
// create block device and configuration
lfs_emubd_t bd;
lfs3_emubd_t bd;
jmp_buf powerloss_jmp;
struct lfs_config cfg = {
struct lfs3_config cfg = {
.context = &bd,
.read = lfs_emubd_read,
.prog = lfs_emubd_prog,
.erase = lfs_emubd_erase,
.sync = lfs_emubd_sync,
.read = lfs3_emubd_read,
.prog = lfs3_emubd_prog,
.erase = lfs3_emubd_erase,
.sync = lfs3_emubd_sync,
TEST_CFG
};
struct lfs_emubd_config bdcfg = {
struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path,
.read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep,
@@ -1461,7 +1461,7 @@ static void run_powerloss_log(
TEST_BDCFG
};
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1);
@@ -1488,7 +1488,7 @@ static void run_powerloss_log(
// increment pls
TEST_PLS += 1;
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
? 1 << TEST_PLS
: 0);
}
@@ -1498,7 +1498,7 @@ static void run_powerloss_log(
printf("\n");
// cleanup
err = lfs_emubd_destroy(&cfg);
err = lfs3_emubd_destroy(&cfg);
if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1);
@@ -1513,19 +1513,19 @@ static void run_powerloss_cycles(
TEST_PLS = 0;
// create block device and configuration
lfs_emubd_t bd;
lfs3_emubd_t bd;
jmp_buf powerloss_jmp;
struct lfs_config cfg = {
struct lfs3_config cfg = {
.context = &bd,
.read = lfs_emubd_read,
.prog = lfs_emubd_prog,
.erase = lfs_emubd_erase,
.sync = lfs_emubd_sync,
.read = lfs3_emubd_read,
.prog = lfs3_emubd_prog,
.erase = lfs3_emubd_erase,
.sync = lfs3_emubd_sync,
TEST_CFG
};
struct lfs_emubd_config bdcfg = {
struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path,
.read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep,
@@ -1538,7 +1538,7 @@ static void run_powerloss_cycles(
TEST_BDCFG
};
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1);
@@ -1564,7 +1564,7 @@ static void run_powerloss_cycles(
// increment pls
TEST_PLS += 1;
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
? powerloss->cycles[TEST_PLS]
: 0);
}
@@ -1574,7 +1574,7 @@ static void run_powerloss_cycles(
printf("\n");
// cleanup
err = lfs_emubd_destroy(&cfg);
err = lfs3_emubd_destroy(&cfg);
if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1);
@@ -1582,15 +1582,15 @@ static void run_powerloss_cycles(
}
struct powerloss_exhaustive_state {
struct lfs_config *cfg;
struct lfs3_config *cfg;
lfs_emubd_t *branches;
lfs3_emubd_t *branches;
size_t branch_count;
size_t branch_capacity;
};
struct powerloss_exhaustive_cycles {
lfs_emubd_powercycles_t *cycles;
lfs3_emubd_powercycles_t *cycles;
size_t cycle_count;
size_t cycle_capacity;
};
@@ -1598,9 +1598,9 @@ struct powerloss_exhaustive_cycles {
static void powerloss_exhaustive_branch(void *c) {
struct powerloss_exhaustive_state *state = c;
// append to branches
lfs_emubd_t *branch = mappend(
lfs3_emubd_t *branch = mappend(
(void**)&state->branches,
sizeof(lfs_emubd_t),
sizeof(lfs3_emubd_t),
&state->branch_count,
&state->branch_capacity);
if (!branch) {
@@ -1609,22 +1609,22 @@ static void powerloss_exhaustive_branch(void *c) {
}
// create copy-on-write copy
int err = lfs_emubd_cpy(state->cfg, branch);
int err = lfs3_emubd_cpy(state->cfg, branch);
if (err) {
fprintf(stderr, "error: exhaustive: could not create bd copy\n");
exit(-1);
}
// also trigger on next power cycle
lfs_emubd_setpowercycles(state->cfg, 1);
lfs3_emubd_setpowercycles(state->cfg, 1);
}
static void run_powerloss_exhaustive_layer(
struct powerloss_exhaustive_cycles *cycles,
const struct test_suite *suite,
const struct test_case *case_,
struct lfs_config *cfg,
struct lfs_emubd_config *bdcfg,
struct lfs3_config *cfg,
struct lfs3_emubd_config *bdcfg,
size_t depth,
size_t pls) {
struct powerloss_exhaustive_state state = {
@@ -1639,14 +1639,14 @@ static void run_powerloss_exhaustive_layer(
// run through the test without additional powerlosses, collecting possible
// branches as we do so
lfs_emubd_setpowercycles(state.cfg, (depth > 0) ? 1 : 0);
lfs3_emubd_setpowercycles(state.cfg, (depth > 0) ? 1 : 0);
bdcfg->powerloss_data = &state;
// run the tests
case_->run(cfg);
// aggressively clean up memory here to try to keep our memory usage low
int err = lfs_emubd_destroy(cfg);
int err = lfs3_emubd_destroy(cfg);
if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1);
@@ -1655,9 +1655,9 @@ static void run_powerloss_exhaustive_layer(
// recurse into each branch
for (size_t i = 0; i < state.branch_count; i++) {
// first push and print the branch
lfs_emubd_powercycles_t *cycle = mappend(
lfs3_emubd_powercycles_t *cycle = mappend(
(void**)&cycles->cycles,
sizeof(lfs_emubd_powercycles_t),
sizeof(lfs3_emubd_powercycles_t),
&cycles->cycle_count,
&cycles->cycle_capacity);
if (!cycle) {
@@ -1689,18 +1689,18 @@ static void run_powerloss_exhaustive(
const struct test_suite *suite,
const struct test_case *case_) {
// create block device and configuration
lfs_emubd_t bd;
lfs3_emubd_t bd;
struct lfs_config cfg = {
struct lfs3_config cfg = {
.context = &bd,
.read = lfs_emubd_read,
.prog = lfs_emubd_prog,
.erase = lfs_emubd_erase,
.sync = lfs_emubd_sync,
.read = lfs3_emubd_read,
.prog = lfs3_emubd_prog,
.erase = lfs3_emubd_erase,
.sync = lfs3_emubd_sync,
TEST_CFG
};
struct lfs_emubd_config bdcfg = {
struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path,
.read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep,
@@ -1710,7 +1710,7 @@ static void run_powerloss_exhaustive(
TEST_BDCFG
};
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1);
@@ -2234,16 +2234,16 @@ int main(int argc, char **argv) {
// comma-separated permutation
if (*optarg == '{') {
lfs_emubd_powercycles_t *cycles = NULL;
lfs3_emubd_powercycles_t *cycles = NULL;
size_t cycle_count = 0;
size_t cycle_capacity = 0;
char *s = optarg + 1;
while (true) {
parsed = NULL;
*(lfs_emubd_powercycles_t*)mappend(
*(lfs3_emubd_powercycles_t*)mappend(
(void**)&cycles,
sizeof(lfs_emubd_powercycles_t),
sizeof(lfs3_emubd_powercycles_t),
&cycle_count,
&cycle_capacity)
= strtoumax(s, &parsed, 0);
@@ -2295,7 +2295,7 @@ int main(int argc, char **argv) {
// otherwise explicit power cycles
} else {
lfs_emubd_powercycles_t *cycles = NULL;
lfs3_emubd_powercycles_t *cycles = NULL;
size_t cycle_count = 0;
size_t cycle_capacity = 0;
@@ -2307,9 +2307,9 @@ int main(int argc, char **argv) {
break;
}
*(lfs_emubd_powercycles_t*)mappend(
*(lfs3_emubd_powercycles_t*)mappend(
(void**)&cycles,
sizeof(lfs_emubd_powercycles_t),
sizeof(lfs3_emubd_powercycles_t),
&cycle_count,
&cycle_capacity) = x;
s = parsed;
@@ -2538,7 +2538,7 @@ getopt_done:;
if (d >= define_count) {
// align to power of two to avoid any superlinear growth
size_t ncount = 1 << lfs_nlog2(d+1);
size_t ncount = 1 << lfs3_nlog2(d+1);
defines = realloc(defines,
ncount*sizeof(test_define_t));
memset(defines+define_count, 0,
@@ -2588,14 +2588,14 @@ getopt_done:;
// otherwise explicit power cycles
} else if (cycles_) {
// parse power cycles
lfs_emubd_powercycles_t *cycles = NULL;
lfs3_emubd_powercycles_t *cycles = NULL;
size_t cycle_count = 0;
size_t cycle_capacity = 0;
while (*cycles_ != '\0') {
char *parsed = NULL;
*(lfs_emubd_powercycles_t*)mappend(
*(lfs3_emubd_powercycles_t*)mappend(
(void**)&cycles,
sizeof(lfs_emubd_powercycles_t),
sizeof(lfs3_emubd_powercycles_t),
&cycle_count,
&cycle_capacity)
= leb16_parse(cycles_, &parsed);
+13 -13
View File
@@ -8,20 +8,20 @@
#define TEST_RUNNER_H
// override LFS_TRACE
// override LFS3_TRACE
void test_trace(const char *fmt, ...);
#define LFS_TRACE_(fmt, ...) \
#define LFS3_TRACE_(fmt, ...) \
test_trace("%s:%d:trace: " fmt "%s\n", \
__FILE__, \
__LINE__, \
__VA_ARGS__)
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
#define LFS_EMUBD_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
#define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
#define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
// note these are indirectly included in any generated files
#include "bd/lfs_emubd.h"
#include "bd/lfs3_emubd.h"
#include <stdio.h>
// give source a chance to define feature macros
@@ -30,7 +30,7 @@ void test_trace(const char *fmt, ...);
// generated test configurations
struct lfs_config;
struct lfs3_config;
enum test_flags {
TEST_INTERNAL = 0x1,
@@ -56,7 +56,7 @@ struct test_case {
size_t permutations;
bool (*if_)(void);
void (*run)(struct lfs_config *cfg);
void (*run)(struct lfs3_config *cfg);
};
struct test_suite {
@@ -101,21 +101,21 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
TEST_DEFINE(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \
TEST_DEFINE(DISK_SIZE, 1024*1024 ) \
TEST_DEFINE(BLOCK_RECYCLES, -1 ) \
TEST_DEFINE(RCACHE_SIZE, LFS_MAX(16, READ_SIZE) ) \
TEST_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
TEST_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) ) \
TEST_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \
TEST_DEFINE(FILE_CACHE_SIZE, 16 ) \
TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \
TEST_DEFINE(GC_FLAGS, 0 ) \
TEST_DEFINE(GC_STEPS, 0 ) \
TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \
TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
TEST_DEFINE(FRAGMENT_SIZE, LFS_MIN(BLOCK_SIZE/8, 512) ) \
TEST_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/8, 512) ) \
TEST_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
TEST_DEFINE(FRAGMENT_THRESH, -1 ) \
TEST_DEFINE(ERASE_VALUE, 0xff ) \
TEST_DEFINE(ERASE_CYCLES, 0 ) \
TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS_EMUBD_BADBLOCK_PROGERROR ) \
TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS_EMUBD_POWERLOSS_ATOMIC ) \
TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) \
TEST_DEFINE(EMUBD_SEED, 0 )
// declare defines as global intmax_ts
@@ -143,7 +143,7 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
.crystal_thresh = CRYSTAL_THRESH, \
.fragment_thresh = FRAGMENT_THRESH,
#ifdef LFS_GC
#ifdef LFS3_GC
#define TEST_GC_CFG \
.gc_flags = GC_FLAGS, \
.gc_steps = GC_STEPS,
+2 -2
View File
@@ -432,7 +432,7 @@ def compile(bench_paths, **args):
# create case run function
f.writeln('void __bench__%s__run('
'__attribute__((unused)) '
'struct lfs_config *CFG) {' % (
'struct lfs3_config *CFG) {' % (
case.name))
f.writeln(4*' '+'// bench case %s' % case.name)
if case.code_lineno is not None:
@@ -491,7 +491,7 @@ def compile(bench_paths, **args):
'void);' % (
case.name))
f.writeln('extern void __bench__%s__run('
'struct lfs_config *CFG);' % (
'struct lfs3_config *CFG);' % (
case.name))
f.writeln()
+5 -5
View File
@@ -2769,7 +2769,7 @@ class Gstate:
# high-level littlefs representation
class Lfs:
class Lfs3:
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
corrupt=False):
self.bd = bd
@@ -3018,7 +3018,7 @@ class Lfs:
# empty path?
if path_ == b'':
raise Lfs.PathError("invalid path: %r" % path)
raise Lfs3.PathError("invalid path: %r" % path)
path__ = []
for p in path_.split(b'/'):
@@ -3039,7 +3039,7 @@ class Lfs:
else:
path__.append(p)
if dotdots:
raise Lfs.PathError("invalid path: %r" % path)
raise Lfs3.PathError("invalid path: %r" % path)
path__.reverse()
path_ = path__
@@ -3570,7 +3570,7 @@ class Lfs:
super().__init__(lfs, mid, mdir, tag, name)
# we're recursable if we're a non-grmed directory with a did
if (isinstance(self, Lfs.Dir)
if (isinstance(self, Lfs3.Dir)
and not self.grmed
and self.did is not None):
self.recursable = True
@@ -4507,7 +4507,7 @@ def main_(ring, disk, mroots=None, *,
# fetch the filesystem
bd = Bd(f, block_size, block_count)
lfs = Lfs.fetch(bd, mroots, trunk,
lfs = Lfs3.fetch(bd, mroots, trunk,
# don't bother to check things if we're not reporting errors
no_ck=not args.get('error_on_corrupt'))
corrupted = not bool(lfs)
+5 -5
View File
@@ -2799,7 +2799,7 @@ class Gstate:
# high-level littlefs representation
class Lfs:
class Lfs3:
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
corrupt=False):
self.bd = bd
@@ -3048,7 +3048,7 @@ class Lfs:
# empty path?
if path_ == b'':
raise Lfs.PathError("invalid path: %r" % path)
raise Lfs3.PathError("invalid path: %r" % path)
path__ = []
for p in path_.split(b'/'):
@@ -3069,7 +3069,7 @@ class Lfs:
else:
path__.append(p)
if dotdots:
raise Lfs.PathError("invalid path: %r" % path)
raise Lfs3.PathError("invalid path: %r" % path)
path__.reverse()
path_ = path__
@@ -3600,7 +3600,7 @@ class Lfs:
super().__init__(lfs, mid, mdir, tag, name)
# we're recursable if we're a non-grmed directory with a did
if (isinstance(self, Lfs.Dir)
if (isinstance(self, Lfs3.Dir)
and not self.grmed
and self.did is not None):
self.recursable = True
@@ -4227,7 +4227,7 @@ def main(disk, output, mroots=None, *,
# fetch the filesystem
bd = Bd(f, block_size, block_count)
lfs = Lfs.fetch(bd, mroots, trunk)
lfs = Lfs3.fetch(bd, mroots, trunk)
corrupted = not bool(lfs)
# if we can't figure out the block_count, guess
+4 -4
View File
@@ -35,14 +35,14 @@ def main(errs, *,
# list all known error codes
if list_:
for n, e, h in ERRS:
lines.append(('LFS_ERR_'+n, str(e), h))
lines.append(('LFS3_ERR_'+n, str(e), h))
# find these errors
else:
def find_err(err):
# find by LFS_ERR_+name
# find by LFS3_ERR_+name
for n, e, h in ERRS:
if 'LFS_ERR_'+n == err.upper():
if 'LFS3_ERR_'+n == err.upper():
return n, e, h
# find by ERR_+name
for n, e, h in ERRS:
@@ -73,7 +73,7 @@ def main(errs, *,
for err in errs:
try:
n, e, h = find_err(err)
lines.append(('LFS_ERR_'+n, str(e), h))
lines.append(('LFS3_ERR_'+n, str(e), h))
except KeyError:
lines.append(('?', err, 'Unknown err code'))
+22 -22
View File
@@ -77,8 +77,8 @@ FLAGS = [
('M', 'MODE', 1, "Mount's access mode" ),
('^', 'RDWR', 0, "Mount the filesystem as read and write" ),
('^', 'RDONLY', 1, "Mount the filesystem as read only" ),
('M', 'FLUSH', 0x00000040, "Open all files with LFS_O_FLUSH" ),
('M', 'SYNC', 0x00000080, "Open all files with LFS_O_SYNC" ),
('M', 'FLUSH', 0x00000040, "Open all files with LFS3_O_FLUSH" ),
('M', 'SYNC', 0x00000080, "Open all files with LFS3_O_SYNC" ),
('M', 'REVDBG', 0x00000010, "Add debug info to revision counts" ),
('M', 'REVNOISE', 0x00000020, "Add noise to revision counts" ),
('M', 'CKPROGS', 0x00080000, "Check progs by reading back progged data" ),
@@ -105,16 +105,16 @@ FLAGS = [
# Filesystem info flags
('I', 'RDONLY', 0x00000001, "Mounted read only" ),
('I', 'FLUSH', 0x00000040, "Mounted with LFS_M_FLUSH" ),
('I', 'SYNC', 0x00000080, "Mounted with LFS_M_SYNC" ),
('I', 'REVDBG', 0x00000010, "Mounted with LFS_M_REVDBG" ),
('I', 'REVNOISE', 0x00000020, "Mounted with LFS_M_REVNOISE" ),
('I', 'CKPROGS', 0x00080000, "Mounted with LFS_M_CKPROGS" ),
('I', 'CKFETCHES', 0x00100000, "Mounted with LFS_M_CKFETCHES" ),
('I', 'FLUSH', 0x00000040, "Mounted with LFS3_M_FLUSH" ),
('I', 'SYNC', 0x00000080, "Mounted with LFS3_M_SYNC" ),
('I', 'REVDBG', 0x00000010, "Mounted with LFS3_M_REVDBG" ),
('I', 'REVNOISE', 0x00000020, "Mounted with LFS3_M_REVNOISE" ),
('I', 'CKPROGS', 0x00080000, "Mounted with LFS3_M_CKPROGS" ),
('I', 'CKFETCHES', 0x00100000, "Mounted with LFS3_M_CKFETCHES" ),
('I', 'CKMETAPARITY',
0x00200000, "Mounted with LFS_M_CKMETAPARITY" ),
0x00200000, "Mounted with LFS3_M_CKMETAPARITY" ),
('I', 'CKDATACKSUMREADS',
0x00800000, "Mounted with LFS_M_CKDATACKSUMREADS" ),
0x00800000, "Mounted with LFS3_M_CKDATACKSUMREADS" ),
('I', 'MKCONSISTENT',
0x00000100, "Filesystem needs mkconsistent to write" ),
@@ -233,10 +233,10 @@ def main(flags, *,
# accept prefix prefix
if f.upper() in prefixes:
prefix.update(prefixes[f.upper()])
# accept LFS_+prefix prefix
elif (f.upper().startswith('LFS_')
and f.upper()[len('LFS_'):] in prefixes):
prefix.update(prefixes[f.upper()[len('LFS_'):]])
# accept LFS3_+prefix prefix
elif (f.upper().startswith('LFS3_')
and f.upper()[len('LFS3_'):] in prefixes):
prefix.update(prefixes[f.upper()[len('LFS3_'):]])
else:
flags_.append(f)
@@ -261,30 +261,30 @@ def main(flags, *,
for p, t, n, f, h in flags__:
if not all_ and (t is not None or p[0].islower()):
continue
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h))
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
# find flags by name or value
else:
for f_ in flags_:
found = False
# find by LFS_+prefix+_+name
# find by LFS3_+prefix+_+name
for p, t, n, f, h in flags__:
if 'LFS_%s_%s' % (p, n) == f_.upper():
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h))
if 'LFS3_%s_%s' % (p, n) == f_.upper():
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
found = True
if found:
continue
# find by prefix+_+name
for p, t, n, f, h in flags__:
if '%s_%s' % (p, n) == f_.upper():
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h))
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
found = True
if found:
continue
# find by name
for p, t, n, f, h in flags__:
if n == f_.upper():
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h))
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
found = True
if found:
continue
@@ -298,11 +298,11 @@ def main(flags, *,
continue
# matches flag?
if t is None and (f__ & f) == f:
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h))
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
f___ &= ~f
# matches type?
elif t is not None and (f__ & t) == f:
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h))
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
f___ &= ~t
if f___:
lines.append(('?', '0x%08x' % f___, 'Unknown flags'))
+8 -8
View File
@@ -2726,7 +2726,7 @@ class Gstate:
# high-level littlefs representation
class Lfs:
class Lfs3:
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
corrupt=False):
self.bd = bd
@@ -2975,7 +2975,7 @@ class Lfs:
# empty path?
if path_ == b'':
raise Lfs.PathError("invalid path: %r" % path)
raise Lfs3.PathError("invalid path: %r" % path)
path__ = []
for p in path_.split(b'/'):
@@ -2996,7 +2996,7 @@ class Lfs:
else:
path__.append(p)
if dotdots:
raise Lfs.PathError("invalid path: %r" % path)
raise Lfs3.PathError("invalid path: %r" % path)
path__.reverse()
path_ = path__
@@ -3527,7 +3527,7 @@ class Lfs:
super().__init__(lfs, mid, mdir, tag, name)
# we're recursable if we're a non-grmed directory with a did
if (isinstance(self, Lfs.Dir)
if (isinstance(self, Lfs3.Dir)
and not self.grmed
and self.did is not None):
self.recursable = True
@@ -4157,7 +4157,7 @@ def dbg_files(lfs, paths, *,
try:
dir = lfs.pathlookup(path,
all=args.get('all'))
except Lfs.PathError as e:
except Lfs3.PathError as e:
print("error: %s" % e,
file=sys.stderr)
sys.exit(-1)
@@ -4178,7 +4178,7 @@ def dbg_files(lfs, paths, *,
# include any orphaned entries in the root directory to help
# debugging (these don't actually live in the root directory)
if not no_orphans and isinstance(dir, Lfs.Root):
if not no_orphans and isinstance(dir, Lfs3.Root):
# finding orphans is expensive, so cache this
if not hasattr(iter_dir, 'orphans'):
iter_dir.orphans = dir.lfs.orphans()
@@ -4224,7 +4224,7 @@ def dbg_files(lfs, paths, *,
if file.orphaned:
notes.append('orphaned')
# missing bookmark/did?
if isinstance(file, Lfs.Dir):
if isinstance(file, Lfs3.Dir):
if file.did is None:
notes.append('missing did')
elif lfs.namelookup(file.did, b'') is None:
@@ -4582,7 +4582,7 @@ def main(disk, mroots=None, paths=None, *,
# fetch the filesystem
bd = Bd(f, block_size, block_count)
lfs = Lfs.fetch(bd, mroots, trunk)
lfs = Lfs3.fetch(bd, mroots, trunk)
# print some information about the filesystem
if not quiet:
+2 -2
View File
@@ -444,7 +444,7 @@ def compile(test_paths, **args):
# create case run function
f.writeln('void __test__%s__run('
'__attribute__((unused)) '
'struct lfs_config *CFG) {' % (
'struct lfs3_config *CFG) {' % (
case.name))
f.writeln(4*' '+'// test case %s' % case.name)
if case.code_lineno is not None:
@@ -503,7 +503,7 @@ def compile(test_paths, **args):
'void);' % (
case.name))
f.writeln('extern void __test__%s__run('
'struct lfs_config *CFG);' % (
'struct lfs3_config *CFG);' % (
case.name))
f.writeln()
+240 -240
View File
@@ -20,23 +20,23 @@ defines.COUNT = [
'2',
]
defines.ERASE = [false, true]
in = 'lfs.c'
in = 'lfs3.c'
code = '''
// test various block counts
struct lfs_config cfg = *CFG;
struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT;
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// start allocating
lfs_alloc_ckpoint(&lfs);
lfs_size_t alloced = 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_size_t alloced = 0;
while (true) {
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
assert(block >= 0 || block == LFS_ERR_NOSPC);
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
assert(block >= 0 || block == LFS3_ERR_NOSPC);
if (block == LFS_ERR_NOSPC) {
if (block == LFS3_ERR_NOSPC) {
break;
}
alloced += 1;
@@ -47,10 +47,10 @@ code = '''
// excluding our mroot, we should have allocated exactly
// block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)COUNT);
printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
assert(alloced == COUNT-2);
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
# test that we can realloc after an ack
@@ -64,23 +64,23 @@ defines.COUNT = [
'2',
]
defines.ERASE = [false, true]
in = 'lfs.c'
in = 'lfs3.c'
code = '''
// test various block counts
struct lfs_config cfg = *CFG;
struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT;
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// start allocating
lfs_alloc_ckpoint(&lfs);
lfs_size_t alloced = 0;
lfs3_alloc_ckpoint(&lfs3);
lfs3_size_t alloced = 0;
while (true) {
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
assert(block >= 0 || block == LFS_ERR_NOSPC);
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
assert(block >= 0 || block == LFS3_ERR_NOSPC);
if (block == LFS_ERR_NOSPC) {
if (block == LFS3_ERR_NOSPC) {
break;
}
alloced += 1;
@@ -91,17 +91,17 @@ code = '''
// excluding our mroot, we should have allocated exactly
// block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)COUNT);
printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
assert(alloced == COUNT-2);
// ack again, effectively releasing all the previously alloced blocks
lfs_alloc_ckpoint(&lfs);
lfs3_alloc_ckpoint(&lfs3);
alloced = 0;
while (true) {
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
assert(block >= 0 || block == LFS_ERR_NOSPC);
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
assert(block >= 0 || block == LFS3_ERR_NOSPC);
if (block == LFS_ERR_NOSPC) {
if (block == LFS3_ERR_NOSPC) {
break;
}
alloced += 1;
@@ -112,10 +112,10 @@ code = '''
// excluding our mroot, we should have allocated exactly
// block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)COUNT);
printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
assert(alloced == COUNT-2);
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
@@ -124,81 +124,81 @@ code = '''
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
defines.CKMETA = [false, true]
defines.REMOUNT = [false, true]
in = 'lfs.c'
in = 'lfs3.c'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// create this many directories
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "dir%03x", i);
lfsr_mkdir(&lfs, name) => 0;
lfs3_mkdir(&lfs3, name) => 0;
}
// check that our mkdir worked
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "dir%03x", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfsr_dir_t dir;
lfsr_dir_open(&lfs, &dir, "/") => 0;
struct lfs_info info;
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "dir%03x", i);
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
lfsr_dir_close(&lfs, &dir) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
// remount?
if (REMOUNT) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
}
// first traverse the tree to find all blocks in use
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfsr_traversal_t t;
lfsr_traversal_init(&t,
LFS_T_RDONLY
| ((CKMETA) ? LFS_T_CKMETA : 0));
for (lfs_block_t i = 0;; i++) {
lfs3_traversal_t t;
lfs3_traversal_init(&t,
LFS3_T_RDONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
for (lfs3_block_t i = 0;; i++) {
// a bit hacky, but this catches infinite loops
assert(i < 2*BLOCK_COUNT);
lfsr_tag_t tag;
lfsr_bptr_t bptr;
int err = lfsr_mtree_traverse(&lfs, &t,
lfs3_tag_t tag;
lfs3_bptr_t bptr;
int err = lfs3_mtree_traverse(&lfs3, &t,
&tag, &bptr);
assert(!err || err == LFS_ERR_NOENT);
if (err == LFS_ERR_NOENT) {
assert(!err || err == LFS3_ERR_NOENT);
if (err == LFS3_ERR_NOENT) {
break;
}
if (tag == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
if (tag == LFS3_TAG_MDIR) {
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
tag,
mdir->rbyd.blocks[0],
@@ -208,8 +208,8 @@ code = '''
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
} else if (tag == LFSR_TAG_BRANCH) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
} else if (tag == LFS3_TAG_BRANCH) {
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
printf("traversal: 0x%x btree 0x%x.%x\n",
tag,
rbyd->blocks[0], rbyd->trunk);
@@ -227,7 +227,7 @@ code = '''
// then clobber every other block
uint8_t clobber_buf[BLOCK_SIZE];
memset(clobber_buf, 0xcc, BLOCK_SIZE);
for (lfs_block_t block = 0; block < BLOCK_COUNT; block++) {
for (lfs3_block_t block = 0; block < BLOCK_COUNT; block++) {
if (!(seen[block / 8] & (1 << (block % 8)))) {
CFG->erase(CFG, block) => 0;
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
@@ -239,42 +239,42 @@ code = '''
for (int remount = 0; remount < 2; remount++) {
// remount?
if (remount) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
}
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "dir%03x", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfsr_dir_open(&lfs, &dir, "/") => 0;
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "dir%03x", i);
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
lfsr_dir_close(&lfs, &dir) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
}
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
[cases.test_alloc_clobber_files]
@@ -290,86 +290,86 @@ defines.SIZE = [
]
defines.CKMETA = [false, true]
defines.REMOUNT = [false, true]
in = 'lfs.c'
in = 'lfs3.c'
if = '(SIZE*N)/BLOCK_SIZE <= 32'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// create this many files
uint32_t prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "file%03x", i);
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_t file;
lfsr_file_open(&lfs, &file, name,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE;
lfsr_file_close(&lfs, &file) => 0;
lfs3_file_t file;
lfs3_file_open(&lfs3, &file, name,
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
lfs3_file_close(&lfs3, &file) => 0;
}
// check that our writes worked
prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
// check with stat
char name[256];
sprintf(name, "file%03x", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
// try reading the file, note we reset prng above
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_t file;
lfs3_file_t file;
uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0;
lfs3_file_close(&lfs3, &file) => 0;
}
// remount?
if (REMOUNT) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
}
// first traverse the tree to find all blocks in use
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfsr_traversal_t t;
lfsr_traversal_init(&t,
LFS_T_RDONLY
| ((CKMETA) ? LFS_T_CKMETA : 0));
for (lfs_block_t i = 0;; i++) {
lfs3_traversal_t t;
lfs3_traversal_init(&t,
LFS3_T_RDONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
for (lfs3_block_t i = 0;; i++) {
// a bit hacky, but this catches infinite loops
assert(i < 2*BLOCK_COUNT);
lfsr_tag_t tag;
lfsr_bptr_t bptr;
int err = lfsr_mtree_traverse(&lfs, &t,
lfs3_tag_t tag;
lfs3_bptr_t bptr;
int err = lfs3_mtree_traverse(&lfs3, &t,
&tag, &bptr);
assert(!err || err == LFS_ERR_NOENT);
if (err == LFS_ERR_NOENT) {
assert(!err || err == LFS3_ERR_NOENT);
if (err == LFS3_ERR_NOENT) {
break;
}
if (tag == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
if (tag == LFS3_TAG_MDIR) {
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
tag,
mdir->rbyd.blocks[0],
@@ -379,8 +379,8 @@ code = '''
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
} else if (tag == LFSR_TAG_BRANCH) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
} else if (tag == LFS3_TAG_BRANCH) {
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
printf("traversal: 0x%x btree 0x%x.%x\n",
tag,
rbyd->blocks[0], rbyd->trunk);
@@ -388,7 +388,7 @@ code = '''
// keep track of seen blocks
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
} else if (tag == LFSR_TAG_BLOCK) {
} else if (tag == LFS3_TAG_BLOCK) {
printf("traversal: 0x%x block 0x%x\n",
tag,
bptr.data.u.disk.block);
@@ -407,7 +407,7 @@ code = '''
// then clobber every other block
uint8_t clobber_buf[BLOCK_SIZE];
memset(clobber_buf, 0xcc, BLOCK_SIZE);
for (lfs_block_t block = 0; block < BLOCK_COUNT; block++) {
for (lfs3_block_t block = 0; block < BLOCK_COUNT; block++) {
if (!(seen[block / 8] & (1 << (block % 8)))) {
CFG->erase(CFG, block) => 0;
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
@@ -419,37 +419,37 @@ code = '''
for (int remount = 0; remount < 2; remount++) {
// remount?
if (remount) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
}
prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
// check with stat
char name[256];
sprintf(name, "file%03x", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
// try reading the file, note we reset prng above
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_t file;
lfs3_file_t file;
uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0;
lfs3_file_close(&lfs3, &file) => 0;
}
}
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
# open files need to be tracked internally to make sure this doesn't break
@@ -465,42 +465,42 @@ defines.SIZE = [
'8*BLOCK_SIZE',
]
defines.CKMETA = [false, true]
in = 'lfs.c'
in = 'lfs3.c'
if = '(SIZE*N)/BLOCK_SIZE <= 32'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// create this many files
lfsr_file_t files[N];
lfs3_file_t files[N];
uint32_t prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
char name[256];
sprintf(name, "file%03x", i);
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_open(&lfs, &files[i], name,
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0;
lfsr_file_write(&lfs, &files[i], wbuf, SIZE) => SIZE;
lfs3_file_open(&lfs3, &files[i], name,
LFS3_O_RDWR | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
lfs3_file_write(&lfs3, &files[i], wbuf, SIZE) => SIZE;
}
// check that our writes worked
prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
// try reading the file, note we reset prng above
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
uint8_t rbuf[SIZE];
lfsr_file_rewind(&lfs, &files[i]) => 0;
lfsr_file_read(&lfs, &files[i], rbuf, SIZE) => SIZE;
lfs3_file_rewind(&lfs3, &files[i]) => 0;
lfs3_file_read(&lfs3, &files[i], rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0);
}
@@ -508,25 +508,25 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8);
lfsr_traversal_t t;
lfsr_traversal_init(&t,
LFS_T_RDONLY
| ((CKMETA) ? LFS_T_CKMETA : 0));
for (lfs_block_t i = 0;; i++) {
lfs3_traversal_t t;
lfs3_traversal_init(&t,
LFS3_T_RDONLY
| ((CKMETA) ? LFS3_T_CKMETA : 0));
for (lfs3_block_t i = 0;; i++) {
// a bit hacky, but this catches infinite loops
assert(i < 2*BLOCK_COUNT);
lfsr_tag_t tag;
lfsr_bptr_t bptr;
int err = lfsr_mtree_traverse(&lfs, &t,
lfs3_tag_t tag;
lfs3_bptr_t bptr;
int err = lfs3_mtree_traverse(&lfs3, &t,
&tag, &bptr);
assert(!err || err == LFS_ERR_NOENT);
if (err == LFS_ERR_NOENT) {
assert(!err || err == LFS3_ERR_NOENT);
if (err == LFS3_ERR_NOENT) {
break;
}
if (tag == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
if (tag == LFS3_TAG_MDIR) {
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
tag,
mdir->rbyd.blocks[0],
@@ -538,8 +538,8 @@ code = '''
seen[mdir->rbyd.blocks[0] / 8]
|= 1 << (mdir->rbyd.blocks[0] % 8);
} else if (tag == LFSR_TAG_BRANCH) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
} else if (tag == LFS3_TAG_BRANCH) {
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
printf("traversal: 0x%x btree 0x%x.%x\n",
tag,
rbyd->blocks[0], rbyd->trunk);
@@ -548,7 +548,7 @@ code = '''
seen[rbyd->blocks[0] / 8]
|= 1 << (rbyd->blocks[0] % 8);
} else if (tag == LFSR_TAG_BLOCK) {
} else if (tag == LFS3_TAG_BLOCK) {
printf("traversal: 0x%x block 0x%x\n",
tag,
bptr.data.u.disk.block);
@@ -567,7 +567,7 @@ code = '''
// then clobber every other block
uint8_t clobber_buf[BLOCK_SIZE];
memset(clobber_buf, 0xcc, BLOCK_SIZE);
for (lfs_block_t block = 0; block < BLOCK_COUNT; block++) {
for (lfs3_block_t block = 0; block < BLOCK_COUNT; block++) {
if (!(seen[block / 8] & (1 << (block % 8)))) {
CFG->erase(CFG, block) => 0;
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
@@ -577,58 +577,58 @@ code = '''
// then check that reading our files still works after clobbering
prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
// try reading the file, note we reset prng above
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
uint8_t rbuf[SIZE];
lfsr_file_rewind(&lfs, &files[i]) => 0;
lfsr_file_read(&lfs, &files[i], rbuf, SIZE) => SIZE;
lfs3_file_rewind(&lfs3, &files[i]) => 0;
lfs3_file_read(&lfs3, &files[i], rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0);
}
// and everything is fine after saving the files
for (lfs_size_t i = 0; i < N; i++) {
lfsr_file_close(&lfs, &files[i]) => 0;
for (lfs3_size_t i = 0; i < N; i++) {
lfs3_file_close(&lfs3, &files[i]) => 0;
}
for (int remount = 0; remount < 2; remount++) {
// remount?
if (remount) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
}
prng = 42;
for (lfs_size_t i = 0; i < N; i++) {
for (lfs3_size_t i = 0; i < N; i++) {
// check with stat
char name[256];
sprintf(name, "file%03x", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
// try reading the file, note we reset prng above
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_t file;
lfs3_file_t file;
uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0;
lfs3_file_close(&lfs3, &file) => 0;
}
}
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
@@ -647,20 +647,20 @@ defines.COUNT = [
]
code = '''
// test various block counts
struct lfs_config cfg = *CFG;
struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT;
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// create directories until we run out of space
lfs_size_t n = 0;
lfs3_size_t n = 0;
for (;; n++) {
char name[256];
sprintf(name, "dir%08d", n);
int err = lfsr_mkdir(&lfs, name);
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
int err = lfs3_mkdir(&lfs3, name);
assert(!err || err == LFS3_ERR_NOSPC);
if (err == LFS3_ERR_NOSPC) {
break;
}
}
@@ -668,45 +668,45 @@ code = '''
for (int remount = 0; remount < 2; remount++) {
// remount?
if (remount) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
}
// check that our mkdir worked until we ran out of space
for (lfs_size_t i = 0; i < n; i++) {
for (lfs3_size_t i = 0; i < n; i++) {
char name[256];
sprintf(name, "dir%08d", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfsr_dir_t dir;
lfsr_dir_open(&lfs, &dir, "/") => 0;
struct lfs_info info;
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_t dir;
lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs3_info info;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
for (lfs_size_t i = 0; i < n; i++) {
for (lfs3_size_t i = 0; i < n; i++) {
char name[256];
sprintf(name, "dir%08d", i);
lfsr_dir_read(&lfs, &dir, &info) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR);
assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0);
}
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
lfsr_dir_close(&lfs, &dir) => 0;
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfs3_dir_close(&lfs3, &dir) => 0;
}
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
[cases.test_alloc_nospc_files]
@@ -729,42 +729,42 @@ defines.SIZE = [
]
code = '''
// test various block counts
struct lfs_config cfg = *CFG;
struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT;
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
lfs3_t lfs3;
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// create files until we run out of space
uint32_t prng = 42;
lfs_size_t n = 0;
lfs3_size_t n = 0;
for (;; n++) {
char name[256];
sprintf(name, "file%08d", n);
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_t file;
int err = lfsr_file_open(&lfs, &file, name,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL);
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
lfs3_file_t file;
int err = lfs3_file_open(&lfs3, &file, name,
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL);
assert(!err || err == LFS3_ERR_NOSPC);
if (err == LFS3_ERR_NOSPC) {
break;
}
lfs_ssize_t size = lfsr_file_write(&lfs, &file, wbuf, SIZE);
assert(size == SIZE || size == LFS_ERR_NOSPC);
if (size == LFS_ERR_NOSPC) {
lfsr_file_close(&lfs, &file) => 0;
lfs3_ssize_t size = lfs3_file_write(&lfs3, &file, wbuf, SIZE);
assert(size == SIZE || size == LFS3_ERR_NOSPC);
if (size == LFS3_ERR_NOSPC) {
lfs3_file_close(&lfs3, &file) => 0;
break;
}
err = lfsr_file_close(&lfs, &file);
assert(!err || err == LFS_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) {
err = lfs3_file_close(&lfs3, &file);
assert(!err || err == LFS3_ERR_NOSPC);
if (err == LFS3_ERR_NOSPC) {
break;
}
}
@@ -772,37 +772,37 @@ code = '''
for (int remount = 0; remount < 2; remount++) {
// remount?
if (remount) {
lfsr_unmount(&lfs) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
lfs3_unmount(&lfs3) => 0;
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
}
// check that our file writes worked until we ran out of space
prng = 42;
for (lfs_size_t i = 0; i < n; i++) {
for (lfs3_size_t i = 0; i < n; i++) {
// check with stat
char name[256];
sprintf(name, "file%08d", i);
struct lfs_info info;
lfsr_stat(&lfs, name, &info) => 0;
struct lfs3_info info;
lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG);
assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE);
// try reading the file, note we reset prng above
uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) {
for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
}
lfsr_file_t file;
lfs3_file_t file;
uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0;
lfs3_file_close(&lfs3, &file) => 0;
}
}
lfsr_unmount(&lfs) => 0;
lfs3_unmount(&lfs3) => 0;
'''
+1318 -1308
View File
File diff suppressed because it is too large Load Diff
+1592 -1592
View File
File diff suppressed because it is too large Load Diff
+59 -59
View File
@@ -10,23 +10,23 @@
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = '''
uint8_t buffer[LFS_MAX(READ, PROG)];
uint8_t buffer[LFS3_MAX(READ, PROG)];
// write data
CFG->erase(CFG, 0) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (i+j) % 251;
}
CFG->prog(CFG, 0, i, buffer, PROG) => 0;
}
// read data
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, 0, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (i+j) % 251);
}
}
'''
@@ -35,14 +35,14 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = '''
uint8_t buffer[LFS_MAX(READ, PROG)];
lfs_block_t block;
uint8_t buffer[LFS3_MAX(READ, PROG)];
lfs3_block_t block;
// write block 0
block = 0;
CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251;
}
CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -50,19 +50,19 @@ code = '''
// read block 0
block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
// write block 1
block = 1;
CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251;
}
CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -70,21 +70,21 @@ code = '''
// read block 1
block = 1;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
// read block 0 again
block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
'''
@@ -93,14 +93,14 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = '''
uint8_t buffer[LFS_MAX(READ, PROG)];
lfs_block_t block;
uint8_t buffer[LFS3_MAX(READ, PROG)];
lfs3_block_t block;
// write block 0
block = 0;
CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251;
}
CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -108,19 +108,19 @@ code = '''
// read block 0
block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
// write block n-1
block = CFG->block_count-1;
CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251;
}
CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -128,21 +128,21 @@ code = '''
// read block n-1
block = CFG->block_count-1;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
// read block 0 again
block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
'''
@@ -151,26 +151,26 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = '''
uint8_t buffer[LFS_MAX(READ, PROG)];
uint8_t buffer[LFS3_MAX(READ, PROG)];
// write/read every power of 2
lfs_block_t block = 1;
lfs3_block_t block = 1;
while (block < CFG->block_count) {
// write
CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251;
}
CFG->prog(CFG, block, i, buffer, PROG) => 0;
}
// read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
@@ -181,11 +181,11 @@ code = '''
block = 1;
while (block < CFG->block_count) {
// read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
@@ -197,31 +197,31 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = '''
uint8_t buffer[LFS_MAX(READ, PROG)];
uint8_t buffer[LFS3_MAX(READ, PROG)];
// write/read every fibonacci number on our device
lfs_block_t block = 1;
lfs_block_t block_ = 1;
lfs3_block_t block = 1;
lfs3_block_t block_ = 1;
while (block < CFG->block_count) {
// write
CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251;
}
CFG->prog(CFG, block, i, buffer, PROG) => 0;
}
// read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
lfs_block_t nblock = block + block_;
lfs3_block_t nblock = block + block_;
block_ = block;
block = nblock;
}
@@ -231,15 +231,15 @@ code = '''
block_ = 1;
while (block < CFG->block_count) {
// read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) {
for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
for (lfs3_off_t j = 0; j < READ; j++) {
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
}
}
lfs_block_t nblock = block + block_;
lfs3_block_t nblock = block + block_;
block_ = block;
block = nblock;
}
+1837 -1837
View File
File diff suppressed because it is too large Load Diff
+1559 -1555
View File
File diff suppressed because it is too large Load Diff
+364 -364
View File
File diff suppressed because it is too large Load Diff
+2987 -2987
View File
File diff suppressed because it is too large Load Diff
+639 -639
View File
File diff suppressed because it is too large Load Diff
+427 -427
View File
File diff suppressed because it is too large Load Diff
+1187 -1186
View File
File diff suppressed because it is too large Load Diff
+2637 -2637
View File
File diff suppressed because it is too large Load Diff
+1750 -1740
View File
File diff suppressed because it is too large Load Diff
+1250 -1238
View File
File diff suppressed because it is too large Load Diff
+937 -937
View File
File diff suppressed because it is too large Load Diff
+994 -991
View File
File diff suppressed because it is too large Load Diff
+2150 -2145
View File
File diff suppressed because it is too large Load Diff
+6080 -6080
View File
File diff suppressed because it is too large Load Diff
+287 -285
View File
File diff suppressed because it is too large Load Diff
+7622 -7599
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4487 -4433
View File
File diff suppressed because it is too large Load Diff
+4291 -4267
View File
File diff suppressed because it is too large Load Diff