Big rename! Renamed lfs -> lfs3 and lfsr -> lfs3
This commit is contained in:
+11
-11
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+340
-337
File diff suppressed because it is too large
Load Diff
+265
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+426
-419
File diff suppressed because it is too large
Load Diff
+43
-43
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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'))
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+1592
-1592
File diff suppressed because it is too large
Load Diff
+59
-59
@@ -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
File diff suppressed because it is too large
Load Diff
+1559
-1555
File diff suppressed because it is too large
Load Diff
+364
-364
File diff suppressed because it is too large
Load Diff
+2987
-2987
File diff suppressed because it is too large
Load Diff
+639
-639
File diff suppressed because it is too large
Load Diff
+427
-427
File diff suppressed because it is too large
Load Diff
+1187
-1186
File diff suppressed because it is too large
Load Diff
+2637
-2637
File diff suppressed because it is too large
Load Diff
+1750
-1740
File diff suppressed because it is too large
Load Diff
+1250
-1238
File diff suppressed because it is too large
Load Diff
+937
-937
File diff suppressed because it is too large
Load Diff
+994
-991
File diff suppressed because it is too large
Load Diff
+2150
-2145
File diff suppressed because it is too large
Load Diff
+6080
-6080
File diff suppressed because it is too large
Load Diff
+287
-285
File diff suppressed because it is too large
Load Diff
+7622
-7599
File diff suppressed because it is too large
Load Diff
+537
-535
File diff suppressed because it is too large
Load Diff
+4487
-4433
File diff suppressed because it is too large
Load Diff
+4291
-4267
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user