Big rename! Renamed lfs -> lfs3 and lfsr -> lfs3
This commit is contained in:
+11
-11
@@ -9,21 +9,21 @@
|
|||||||
*.gcno
|
*.gcno
|
||||||
*.gcda
|
*.gcda
|
||||||
*.perf
|
*.perf
|
||||||
lfs
|
lfs3
|
||||||
liblfs.a
|
liblfs3.a
|
||||||
|
|
||||||
# Testing things
|
# Testing things
|
||||||
runners/test_runner
|
runners/test_runner
|
||||||
runners/bench_runner
|
runners/bench_runner
|
||||||
lfs.code.csv
|
lfs3.code.csv
|
||||||
lfs.data.csv
|
lfs3.data.csv
|
||||||
lfs.stack.csv
|
lfs3.stack.csv
|
||||||
lfs.structs.csv
|
lfs3.structs.csv
|
||||||
lfs.cov.csv
|
lfs3.cov.csv
|
||||||
lfs.perf.csv
|
lfs3.perf.csv
|
||||||
lfs.perfbd.csv
|
lfs3.perfbd.csv
|
||||||
lfs.test.csv
|
lfs3.test.csv
|
||||||
lfs.bench.csv
|
lfs3.bench.csv
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
tags
|
tags
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
BUILDDIR ?= .
|
BUILDDIR ?= .
|
||||||
# overrideable target, default to building a library
|
# overrideable target, default to building a library
|
||||||
ifneq ($(wildcard test.c main.c),)
|
ifneq ($(wildcard test.c main.c),)
|
||||||
TARGET ?= $(BUILDDIR)/lfs
|
TARGET ?= $(BUILDDIR)/lfs3
|
||||||
else
|
else
|
||||||
TARGET ?= $(BUILDDIR)/liblfs.a
|
TARGET ?= $(BUILDDIR)/liblfs3.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ else
|
|||||||
CFLAGS += -Os
|
CFLAGS += -Os
|
||||||
endif
|
endif
|
||||||
ifdef TRACE
|
ifdef TRACE
|
||||||
CFLAGS += -DLFS_YES_TRACE
|
CFLAGS += -DLFS3_YES_TRACE
|
||||||
endif
|
endif
|
||||||
ifdef COVGEN
|
ifdef COVGEN
|
||||||
CFLAGS += --coverage
|
CFLAGS += --coverage
|
||||||
@@ -94,8 +94,8 @@ ifdef PERFBDGEN
|
|||||||
CFLAGS += -fno-omit-frame-pointer
|
CFLAGS += -fno-omit-frame-pointer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# also forward all LFS_* environment variables
|
# also forward all LFS3_* environment variables
|
||||||
CFLAGS += $(foreach D,$(filter LFS_%,$(.VARIABLES)),-D$D=$($D))
|
CFLAGS += $(foreach D,$(filter LFS3_%,$(.VARIABLES)),-D$D=$($D))
|
||||||
|
|
||||||
TEST_CFLAGS += -Wno-unused-function
|
TEST_CFLAGS += -Wno-unused-function
|
||||||
TEST_CFLAGS += -Wno-format-overflow
|
TEST_CFLAGS += -Wno-format-overflow
|
||||||
@@ -231,12 +231,12 @@ code: $(OBJ)
|
|||||||
|
|
||||||
## Save the per-function code size
|
## Save the per-function code size
|
||||||
.PHONY: code-csv
|
.PHONY: code-csv
|
||||||
code-csv: $(BUILDDIR)/lfs.code.csv
|
code-csv: $(BUILDDIR)/lfs3.code.csv
|
||||||
|
|
||||||
## Compare per-function code size
|
## Compare per-function code size
|
||||||
.PHONY: code-diff
|
.PHONY: code-diff
|
||||||
code-diff: $(OBJ)
|
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
|
## Find the per-function data size
|
||||||
.PHONY: data
|
.PHONY: data
|
||||||
@@ -246,12 +246,12 @@ data: $(OBJ)
|
|||||||
|
|
||||||
## Save the per-function data size
|
## Save the per-function data size
|
||||||
.PHONY: data-csv
|
.PHONY: data-csv
|
||||||
data-csv: $(BUILDDIR)/lfs.data.csv
|
data-csv: $(BUILDDIR)/lfs3.data.csv
|
||||||
|
|
||||||
## Compare per-function data size
|
## Compare per-function data size
|
||||||
.PHONY: data-diff
|
.PHONY: data-diff
|
||||||
data-diff: $(OBJ)
|
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
|
## Find the per-function stack usage
|
||||||
.PHONY: stack
|
.PHONY: stack
|
||||||
@@ -261,12 +261,12 @@ stack: $(CI)
|
|||||||
|
|
||||||
## Save the per-function stack usage
|
## Save the per-function stack usage
|
||||||
.PHONY: stack-csv
|
.PHONY: stack-csv
|
||||||
stack-csv: $(BUILDDIR)/lfs.stack.csv
|
stack-csv: $(BUILDDIR)/lfs3.stack.csv
|
||||||
|
|
||||||
## Compare per-function stack usage
|
## Compare per-function stack usage
|
||||||
.PHONY: stack-diff
|
.PHONY: stack-diff
|
||||||
stack-diff: $(CI)
|
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
|
## Find the per-function context
|
||||||
.PHONY: ctx
|
.PHONY: ctx
|
||||||
@@ -276,12 +276,12 @@ ctx: $(OBJ)
|
|||||||
|
|
||||||
## Save the per-function context
|
## Save the per-function context
|
||||||
.PHONY: ctx-csv
|
.PHONY: ctx-csv
|
||||||
ctx-csv: $(BUILDDIR)/lfs.ctx.csv
|
ctx-csv: $(BUILDDIR)/lfs3.ctx.csv
|
||||||
|
|
||||||
## Compare per-function context
|
## Compare per-function context
|
||||||
.PHONY: ctx-diff
|
.PHONY: ctx-diff
|
||||||
ctx-diff: $(CI)
|
ctx-diff: $(CI)
|
||||||
./scripts/ctx.py $^ $(CTXFLAGS) -d $(BUILDDIR)/lfs.ctx.csv
|
./scripts/ctx.py $^ $(CTXFLAGS) -d $(BUILDDIR)/lfs3.ctx.csv
|
||||||
|
|
||||||
## Find function sizes
|
## Find function sizes
|
||||||
.PHONY: funcs
|
.PHONY: funcs
|
||||||
@@ -302,9 +302,9 @@ funcs: $(OBJ) $(CI)
|
|||||||
.PHONY: funcs-csv
|
.PHONY: funcs-csv
|
||||||
funcs-csv: SHELL=/bin/bash
|
funcs-csv: SHELL=/bin/bash
|
||||||
funcs-csv: \
|
funcs-csv: \
|
||||||
$(BUILDDIR)/lfs.code.csv \
|
$(BUILDDIR)/lfs3.code.csv \
|
||||||
$(BUILDDIR)/lfs.stack.csv \
|
$(BUILDDIR)/lfs3.stack.csv \
|
||||||
$(BUILDDIR)/lfs.ctx.csv
|
$(BUILDDIR)/lfs3.ctx.csv
|
||||||
|
|
||||||
## Compare function sizes
|
## Compare function sizes
|
||||||
.PHONY: funcs-diff
|
.PHONY: funcs-diff
|
||||||
@@ -319,9 +319,9 @@ funcs-diff: $(OBJ) $(CI)
|
|||||||
-fstack='max(stack_limit)' \
|
-fstack='max(stack_limit)' \
|
||||||
-fctx='max(ctx_size)' \
|
-fctx='max(ctx_size)' \
|
||||||
-d <(./scripts/csv.py \
|
-d <(./scripts/csv.py \
|
||||||
$(BUILDDIR)/lfs.code.csv \
|
$(BUILDDIR)/lfs3.code.csv \
|
||||||
$(BUILDDIR)/lfs.stack.csv \
|
$(BUILDDIR)/lfs3.stack.csv \
|
||||||
$(BUILDDIR)/lfs.ctx.csv \
|
$(BUILDDIR)/lfs3.ctx.csv \
|
||||||
-fcode_size=code_size \
|
-fcode_size=code_size \
|
||||||
-fstack_limit='max(stack_limit)' \
|
-fstack_limit='max(stack_limit)' \
|
||||||
-fctx_size='max(ctx_size)' \
|
-fctx_size='max(ctx_size)' \
|
||||||
@@ -336,12 +336,12 @@ structs: $(OBJ)
|
|||||||
|
|
||||||
## Save struct sizes
|
## Save struct sizes
|
||||||
.PHONY: structs-csv
|
.PHONY: structs-csv
|
||||||
structs-csv: $(BUILDDIR)/lfs.structs.csv
|
structs-csv: $(BUILDDIR)/lfs3.structs.csv
|
||||||
|
|
||||||
## Compare struct sizes
|
## Compare struct sizes
|
||||||
.PHONY: structs-diff
|
.PHONY: structs-diff
|
||||||
structs-diff: $(OBJ)
|
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
|
## Find the line/branch coverage after a test run
|
||||||
.PHONY: cov
|
.PHONY: cov
|
||||||
@@ -353,14 +353,14 @@ cov: $(GCDA)
|
|||||||
|
|
||||||
## Save line/branch coverage
|
## Save line/branch coverage
|
||||||
.PHONY: cov-csv
|
.PHONY: cov-csv
|
||||||
cov-csv: $(BUILDDIR)/lfs.cov.csv
|
cov-csv: $(BUILDDIR)/lfs3.cov.csv
|
||||||
|
|
||||||
## Compare line/branch coverage
|
## Compare line/branch coverage
|
||||||
.PHONY: cov-diff
|
.PHONY: cov-diff
|
||||||
cov-diff: $(GCDA)
|
cov-diff: $(GCDA)
|
||||||
$(strip ./scripts/cov.py $^ \
|
$(strip ./scripts/cov.py $^ \
|
||||||
$(patsubst %,-F%,$(SRC)) \
|
$(patsubst %,-F%,$(SRC)) \
|
||||||
$(COVFLAGS) -d $(BUILDDIR)/lfs.cov.csv)
|
$(COVFLAGS) -d $(BUILDDIR)/lfs3.cov.csv)
|
||||||
|
|
||||||
## Find the perf results after bench run with PERFGEN
|
## Find the perf results after bench run with PERFGEN
|
||||||
.PHONY: perf
|
.PHONY: perf
|
||||||
@@ -372,14 +372,14 @@ perf: $(BENCH_PERF)
|
|||||||
|
|
||||||
## Save perf results
|
## Save perf results
|
||||||
.PHONY: perf-csv
|
.PHONY: perf-csv
|
||||||
perf-csv: $(BUILDDIR)/lfs.perf.csv
|
perf-csv: $(BUILDDIR)/lfs3.perf.csv
|
||||||
|
|
||||||
## Compare perf results
|
## Compare perf results
|
||||||
.PHONY: perf-diff
|
.PHONY: perf-diff
|
||||||
perf-diff: $(BENCH_PERF)
|
perf-diff: $(BENCH_PERF)
|
||||||
$(strip ./scripts/perf.py $^ \
|
$(strip ./scripts/perf.py $^ \
|
||||||
$(patsubst %,-F%,$(SRC)) \
|
$(patsubst %,-F%,$(SRC)) \
|
||||||
$(PERFFLAGS) -d $(BUILDDIR)/lfs.perf.csv)
|
$(PERFFLAGS) -d $(BUILDDIR)/lfs3.perf.csv)
|
||||||
|
|
||||||
## Find the perfbd results after a bench run
|
## Find the perfbd results after a bench run
|
||||||
.PHONY: perfbd
|
.PHONY: perfbd
|
||||||
@@ -391,14 +391,14 @@ perfbd: $(BENCH_TRACE)
|
|||||||
|
|
||||||
## Save perfbd results
|
## Save perfbd results
|
||||||
.PHONY: perfbd-csv
|
.PHONY: perfbd-csv
|
||||||
perfbd-csv: $(BUILDDIR)/lfs.perfbd.csv
|
perfbd-csv: $(BUILDDIR)/lfs3.perfbd.csv
|
||||||
|
|
||||||
## Compare perfbd results
|
## Compare perfbd results
|
||||||
.PHONY: perfbd-diff
|
.PHONY: perfbd-diff
|
||||||
perfbd-diff: $(BENCH_TRACE)
|
perfbd-diff: $(BENCH_TRACE)
|
||||||
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
|
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
|
||||||
$(patsubst %,-F%,$(SRC)) \
|
$(patsubst %,-F%,$(SRC)) \
|
||||||
$(PERFBDFLAGS) -d $(BUILDDIR)/lfs.perfbd.csv)
|
$(PERFBDFLAGS) -d $(BUILDDIR)/lfs3.perfbd.csv)
|
||||||
|
|
||||||
## Find a summary of compile-time sizes
|
## Find a summary of compile-time sizes
|
||||||
.PHONY: summary sizes
|
.PHONY: summary sizes
|
||||||
@@ -420,10 +420,10 @@ summary sizes: $(OBJ) $(CI)
|
|||||||
.PHONY: summary-csv sizes-csv
|
.PHONY: summary-csv sizes-csv
|
||||||
summary-csv sizes-csv: SHELL=/bin/bash
|
summary-csv sizes-csv: SHELL=/bin/bash
|
||||||
summary-csv sizes-csv: \
|
summary-csv sizes-csv: \
|
||||||
$(BUILDDIR)/lfs.code.csv \
|
$(BUILDDIR)/lfs3.code.csv \
|
||||||
$(BUILDDIR)/lfs.data.csv \
|
$(BUILDDIR)/lfs3.data.csv \
|
||||||
$(BUILDDIR)/lfs.stack.csv \
|
$(BUILDDIR)/lfs3.stack.csv \
|
||||||
$(BUILDDIR)/lfs.ctx.csv
|
$(BUILDDIR)/lfs3.ctx.csv
|
||||||
|
|
||||||
## Compare compile-time sizes
|
## Compare compile-time sizes
|
||||||
.PHONY: summary-diff sizes-diff
|
.PHONY: summary-diff sizes-diff
|
||||||
@@ -442,10 +442,10 @@ summary-diff sizes-diff: $(OBJ) $(CI)
|
|||||||
-fctx='max(ctx_size)' \
|
-fctx='max(ctx_size)' \
|
||||||
-o-) \
|
-o-) \
|
||||||
<(./scripts/csv.py \
|
<(./scripts/csv.py \
|
||||||
$(BUILDDIR)/lfs.code.csv \
|
$(BUILDDIR)/lfs3.code.csv \
|
||||||
$(BUILDDIR)/lfs.data.csv \
|
$(BUILDDIR)/lfs3.data.csv \
|
||||||
$(BUILDDIR)/lfs.stack.csv \
|
$(BUILDDIR)/lfs3.stack.csv \
|
||||||
$(BUILDDIR)/lfs.ctx.csv \
|
$(BUILDDIR)/lfs3.ctx.csv \
|
||||||
-bbuild=BEFORE \
|
-bbuild=BEFORE \
|
||||||
-fcode=code_size \
|
-fcode=code_size \
|
||||||
-fdata=data_size \
|
-fdata=data_size \
|
||||||
@@ -458,12 +458,12 @@ summary-diff sizes-diff: $(OBJ) $(CI)
|
|||||||
## Generate a codemap svg
|
## Generate a codemap svg
|
||||||
.PHONY: codemap
|
.PHONY: codemap
|
||||||
codemap: CODEMAPFLAGS+=-W1400 -H750 --dark
|
codemap: CODEMAPFLAGS+=-W1400 -H750 --dark
|
||||||
codemap: $(BUILDDIR)/lfs.codemap.svg
|
codemap: $(BUILDDIR)/lfs3.codemap.svg
|
||||||
|
|
||||||
## Generate a tiny codemap, where 1 pixel ~= 1 byte
|
## Generate a tiny codemap, where 1 pixel ~= 1 byte
|
||||||
.PHONY: codemap-tiny
|
.PHONY: codemap-tiny
|
||||||
codemap-tiny: CODEMAPFLAGS+=--dark
|
codemap-tiny: CODEMAPFLAGS+=--dark
|
||||||
codemap-tiny: $(BUILDDIR)/lfs.codemap_tiny.svg
|
codemap-tiny: $(BUILDDIR)/lfs3.codemap_tiny.svg
|
||||||
|
|
||||||
|
|
||||||
## Build the test-runner
|
## Build the test-runner
|
||||||
@@ -504,7 +504,7 @@ testmarks: $(TEST_CSV)
|
|||||||
|
|
||||||
## Save the test results
|
## Save the test results
|
||||||
.PHONY: testmarks-csv
|
.PHONY: testmarks-csv
|
||||||
testmarks-csv: $(BUILDDIR)/lfs.test.csv
|
testmarks-csv: $(BUILDDIR)/lfs3.test.csv
|
||||||
|
|
||||||
## Compare test results against a previous run
|
## Compare test results against a previous run
|
||||||
.PHONY: testmarks-diff
|
.PHONY: testmarks-diff
|
||||||
@@ -513,7 +513,7 @@ testmarks-diff: $(TEST_CSV)
|
|||||||
-bsuite \
|
-bsuite \
|
||||||
-fpassed=test_passed \
|
-fpassed=test_passed \
|
||||||
-ftime=test_time \
|
-ftime=test_time \
|
||||||
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.test.csv)
|
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs3.test.csv)
|
||||||
|
|
||||||
## Build the bench-runner
|
## Build the bench-runner
|
||||||
.PHONY: bench-runner build-benches
|
.PHONY: bench-runner build-benches
|
||||||
@@ -554,7 +554,7 @@ benchmarks: $(BENCH_CSV)
|
|||||||
|
|
||||||
## Save the bench results
|
## Save the bench results
|
||||||
.PHONY: benchmarks-csv
|
.PHONY: benchmarks-csv
|
||||||
benchmarks-csv: $(BUILDDIR)/lfs.bench.csv
|
benchmarks-csv: $(BUILDDIR)/lfs3.bench.csv
|
||||||
|
|
||||||
## Compare bench results against a previous run
|
## Compare bench results against a previous run
|
||||||
.PHONY: benchmarks-diff
|
.PHONY: benchmarks-diff
|
||||||
@@ -564,7 +564,7 @@ benchmarks-diff: $(BENCH_CSV)
|
|||||||
-freaded=bench_readed \
|
-freaded=bench_readed \
|
||||||
-fproged=bench_proged \
|
-fproged=bench_proged \
|
||||||
-ferased=bench_erased \
|
-ferased=bench_erased \
|
||||||
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.bench.csv)
|
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs3.bench.csv)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -575,54 +575,54 @@ benchmarks-diff: $(BENCH_CSV)
|
|||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
|
|
||||||
$(BUILDDIR)/lfs: $(OBJ)
|
$(BUILDDIR)/lfs3: $(OBJ)
|
||||||
$(CC) $(CFLAGS) $^ $(LFLAGS) -o$@
|
$(CC) $(CFLAGS) $^ $(LFLAGS) -o$@
|
||||||
|
|
||||||
$(BUILDDIR)/liblfs.a: $(OBJ)
|
$(BUILDDIR)/liblfs3.a: $(OBJ)
|
||||||
$(AR) rcs $@ $^
|
$(AR) rcs $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.code.csv: $(OBJ)
|
$(BUILDDIR)/lfs3.code.csv: $(OBJ)
|
||||||
./scripts/code.py $^ $(CODEFLAGS) -o$@
|
./scripts/code.py $^ $(CODEFLAGS) -o$@
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.data.csv: $(OBJ)
|
$(BUILDDIR)/lfs3.data.csv: $(OBJ)
|
||||||
./scripts/data.py $^ $(DATAFLAGS) -o$@
|
./scripts/data.py $^ $(DATAFLAGS) -o$@
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.stack.csv: $(CI)
|
$(BUILDDIR)/lfs3.stack.csv: $(CI)
|
||||||
./scripts/stack.py $^ $(STACKFLAGS) -o$@
|
./scripts/stack.py $^ $(STACKFLAGS) -o$@
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.ctx.csv: $(OBJ)
|
$(BUILDDIR)/lfs3.ctx.csv: $(OBJ)
|
||||||
./scripts/ctx.py $^ $(CTXFLAGS) -o$@
|
./scripts/ctx.py $^ $(CTXFLAGS) -o$@
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.structs.csv: $(OBJ)
|
$(BUILDDIR)/lfs3.structs.csv: $(OBJ)
|
||||||
./scripts/structs.py $^ $(STRUCTSFLAGS) -o$@
|
./scripts/structs.py $^ $(STRUCTSFLAGS) -o$@
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.cov.csv: $(GCDA)
|
$(BUILDDIR)/lfs3.cov.csv: $(GCDA)
|
||||||
$(strip ./scripts/cov.py $^ \
|
$(strip ./scripts/cov.py $^ \
|
||||||
$(patsubst %,-F%,$(SRC)) \
|
$(patsubst %,-F%,$(SRC)) \
|
||||||
$(COVFLAGS) -o$@)
|
$(COVFLAGS) -o$@)
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.perf.csv: $(BENCH_PERF)
|
$(BUILDDIR)/lfs3.perf.csv: $(BENCH_PERF)
|
||||||
$(strip ./scripts/perf.py $^ \
|
$(strip ./scripts/perf.py $^ \
|
||||||
$(patsubst %,-F%,$(SRC)) \
|
$(patsubst %,-F%,$(SRC)) \
|
||||||
$(PERFFLAGS) -o$@)
|
$(PERFFLAGS) -o$@)
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.perfbd.csv: $(BENCH_TRACE)
|
$(BUILDDIR)/lfs3.perfbd.csv: $(BENCH_TRACE)
|
||||||
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
|
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
|
||||||
$(patsubst %,-F%,$(SRC)) \
|
$(patsubst %,-F%,$(SRC)) \
|
||||||
$(PERFBDFLAGS) -o$@)
|
$(PERFBDFLAGS) -o$@)
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.codemap.svg: $(OBJ) $(CI)
|
$(BUILDDIR)/lfs3.codemap.svg: $(OBJ) $(CI)
|
||||||
$(strip ./scripts/codemapsvg.py $^ $(CODEMAPFLAGS) -o$@ \
|
$(strip ./scripts/codemapsvg.py $^ $(CODEMAPFLAGS) -o$@ \
|
||||||
&& ./scripts/codemap.py $^ --no-header)
|
&& ./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$@ \
|
$(strip ./scripts/codemapsvg.py $^ --tiny $(CODEMAPFLAGS) -o$@ \
|
||||||
&& ./scripts/codemap.py $^ --no-header)
|
&& ./scripts/codemap.py $^ --no-header)
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.test.csv: $(TEST_CSV)
|
$(BUILDDIR)/lfs3.test.csv: $(TEST_CSV)
|
||||||
cp $^ $@
|
cp $^ $@
|
||||||
|
|
||||||
$(BUILDDIR)/lfs.bench.csv: $(BENCH_CSV)
|
$(BUILDDIR)/lfs3.bench.csv: $(BENCH_CSV)
|
||||||
cp $^ $@
|
cp $^ $@
|
||||||
|
|
||||||
$(BUILDDIR)/runners/test_runner: $(TEST_OBJ)
|
$(BUILDDIR)/runners/test_runner: $(TEST_OBJ)
|
||||||
@@ -666,20 +666,20 @@ $(BUILDDIR)/%.b.c: %.c $(BENCHES)
|
|||||||
## Clean everything
|
## Clean everything
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -f $(BUILDDIR)/lfs
|
rm -f $(BUILDDIR)/lfs3
|
||||||
rm -f $(BUILDDIR)/liblfs.a
|
rm -f $(BUILDDIR)/liblfs3.a
|
||||||
rm -f $(BUILDDIR)/lfs.code.csv
|
rm -f $(BUILDDIR)/lfs3.code.csv
|
||||||
rm -f $(BUILDDIR)/lfs.data.csv
|
rm -f $(BUILDDIR)/lfs3.data.csv
|
||||||
rm -f $(BUILDDIR)/lfs.stack.csv
|
rm -f $(BUILDDIR)/lfs3.stack.csv
|
||||||
rm -f $(BUILDDIR)/lfs.ctx.csv
|
rm -f $(BUILDDIR)/lfs3.ctx.csv
|
||||||
rm -f $(BUILDDIR)/lfs.structs.csv
|
rm -f $(BUILDDIR)/lfs3.structs.csv
|
||||||
rm -f $(BUILDDIR)/lfs.cov.csv
|
rm -f $(BUILDDIR)/lfs3.cov.csv
|
||||||
rm -f $(BUILDDIR)/lfs.perf.csv
|
rm -f $(BUILDDIR)/lfs3.perf.csv
|
||||||
rm -f $(BUILDDIR)/lfs.perfbd.csv
|
rm -f $(BUILDDIR)/lfs3.perfbd.csv
|
||||||
rm -f $(BUILDDIR)/lfs.codemap.svg
|
rm -f $(BUILDDIR)/lfs3.codemap.svg
|
||||||
rm -f $(BUILDDIR)/lfs.codemap_tiny.svg
|
rm -f $(BUILDDIR)/lfs3.codemap_tiny.svg
|
||||||
rm -f $(BUILDDIR)/lfs.test.csv
|
rm -f $(BUILDDIR)/lfs3.test.csv
|
||||||
rm -f $(BUILDDIR)/lfs.bench.csv
|
rm -f $(BUILDDIR)/lfs3.bench.csv
|
||||||
rm -f $(OBJ)
|
rm -f $(OBJ)
|
||||||
rm -f $(DEP)
|
rm -f $(DEP)
|
||||||
rm -f $(ASM)
|
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.
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
#include "bd/lfs_filebd.h"
|
#include "bd/lfs3_filebd.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
|
int lfs3_filebd_create(const struct lfs3_config *cfg, const char *path) {
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_create(%p {.context=%p, "
|
LFS3_FILEBD_TRACE("lfs3_filebd_create(%p {.context=%p, "
|
||||||
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
|
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
|
||||||
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
|
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
|
||||||
".block_size=%"PRIu32", .block_count=%"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,
|
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
|
||||||
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
|
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
|
||||||
path, (void*)bdcfg, bdcfg->erase_value);
|
path, (void*)bdcfg, bdcfg->erase_value);
|
||||||
lfs_filebd_t *bd = cfg->context;
|
lfs3_filebd_t *bd = cfg->context;
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -37,39 +37,39 @@ int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
|
|||||||
|
|
||||||
if (bd->fd < 0) {
|
if (bd->fd < 0) {
|
||||||
int err = -errno;
|
int err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_create -> %d", err);
|
LFS3_FILEBD_TRACE("lfs3_filebd_create -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_create -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_create -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfs_filebd_destroy(const struct lfs_config *cfg) {
|
int lfs3_filebd_destroy(const struct lfs3_config *cfg) {
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_destroy(%p)", (void*)cfg);
|
LFS3_FILEBD_TRACE("lfs3_filebd_destroy(%p)", (void*)cfg);
|
||||||
lfs_filebd_t *bd = cfg->context;
|
lfs3_filebd_t *bd = cfg->context;
|
||||||
int err = close(bd->fd);
|
int err = close(bd->fd);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_destroy -> %d", err);
|
LFS3_FILEBD_TRACE("lfs3_filebd_destroy -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_destroy -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_destroy -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
|
int lfs3_filebd_read(const struct lfs3_config *cfg, lfs3_block_t block,
|
||||||
lfs_off_t off, void *buffer, lfs_size_t size) {
|
lfs3_off_t off, void *buffer, lfs3_size_t size) {
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_read(%p, "
|
LFS3_FILEBD_TRACE("lfs3_filebd_read(%p, "
|
||||||
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
|
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
|
||||||
(void*)cfg, block, off, buffer, size);
|
(void*)cfg, block, off, buffer, size);
|
||||||
lfs_filebd_t *bd = cfg->context;
|
lfs3_filebd_t *bd = cfg->context;
|
||||||
|
|
||||||
// check if read is valid
|
// check if read is valid
|
||||||
LFS_ASSERT(block < cfg->block_count);
|
LFS3_ASSERT(block < cfg->block_count);
|
||||||
LFS_ASSERT(off % cfg->read_size == 0);
|
LFS3_ASSERT(off % cfg->read_size == 0);
|
||||||
LFS_ASSERT(size % cfg->read_size == 0);
|
LFS3_ASSERT(size % cfg->read_size == 0);
|
||||||
LFS_ASSERT(off+size <= cfg->block_size);
|
LFS3_ASSERT(off+size <= cfg->block_size);
|
||||||
|
|
||||||
// zero for reproducibility (in case file is truncated)
|
// zero for reproducibility (in case file is truncated)
|
||||||
memset(buffer, 0, size);
|
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);
|
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
|
||||||
if (res1 < 0) {
|
if (res1 < 0) {
|
||||||
int err = -errno;
|
int err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err);
|
LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t res2 = read(bd->fd, buffer, size);
|
ssize_t res2 = read(bd->fd, buffer, size);
|
||||||
if (res2 < 0) {
|
if (res2 < 0) {
|
||||||
int err = -errno;
|
int err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err);
|
LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfs_filebd_prog(const struct lfs_config *cfg, lfs_block_t block,
|
int lfs3_filebd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
|
||||||
lfs_off_t off, const void *buffer, lfs_size_t size) {
|
lfs3_off_t off, const void *buffer, lfs3_size_t size) {
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_prog(%p, "
|
LFS3_FILEBD_TRACE("lfs3_filebd_prog(%p, "
|
||||||
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
|
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
|
||||||
(void*)cfg, block, off, buffer, size);
|
(void*)cfg, block, off, buffer, size);
|
||||||
lfs_filebd_t *bd = cfg->context;
|
lfs3_filebd_t *bd = cfg->context;
|
||||||
|
|
||||||
// check if write is valid
|
// check if write is valid
|
||||||
LFS_ASSERT(block < cfg->block_count);
|
LFS3_ASSERT(block < cfg->block_count);
|
||||||
LFS_ASSERT(off % cfg->prog_size == 0);
|
LFS3_ASSERT(off % cfg->prog_size == 0);
|
||||||
LFS_ASSERT(size % cfg->prog_size == 0);
|
LFS3_ASSERT(size % cfg->prog_size == 0);
|
||||||
LFS_ASSERT(off+size <= cfg->block_size);
|
LFS3_ASSERT(off+size <= cfg->block_size);
|
||||||
|
|
||||||
// program data
|
// program data
|
||||||
off_t res1 = lseek(bd->fd,
|
off_t res1 = lseek(bd->fd,
|
||||||
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
|
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
|
||||||
if (res1 < 0) {
|
if (res1 < 0) {
|
||||||
int err = -errno;
|
int err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err);
|
LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t res2 = write(bd->fd, buffer, size);
|
ssize_t res2 = write(bd->fd, buffer, size);
|
||||||
if (res2 < 0) {
|
if (res2 < 0) {
|
||||||
int err = -errno;
|
int err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err);
|
LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfs_filebd_erase(const struct lfs_config *cfg, lfs_block_t block) {
|
int lfs3_filebd_erase(const struct lfs3_config *cfg, lfs3_block_t block) {
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
|
LFS3_FILEBD_TRACE("lfs3_filebd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
|
||||||
(void*)cfg, block, cfg->block_size);
|
(void*)cfg, block, cfg->block_size);
|
||||||
|
|
||||||
// check if erase is valid
|
// check if erase is valid
|
||||||
LFS_ASSERT(block < cfg->block_count);
|
LFS3_ASSERT(block < cfg->block_count);
|
||||||
|
|
||||||
// erase is a noop
|
// erase is a noop
|
||||||
(void)block;
|
(void)block;
|
||||||
|
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_erase -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_erase -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfs_filebd_sync(const struct lfs_config *cfg) {
|
int lfs3_filebd_sync(const struct lfs3_config *cfg) {
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_sync(%p)", (void*)cfg);
|
LFS3_FILEBD_TRACE("lfs3_filebd_sync(%p)", (void*)cfg);
|
||||||
|
|
||||||
// file sync
|
// file sync
|
||||||
lfs_filebd_t *bd = cfg->context;
|
lfs3_filebd_t *bd = cfg->context;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int err = FlushFileBuffers((HANDLE) _get_osfhandle(bd->fd)) ? 0 : -1;
|
int err = FlushFileBuffers((HANDLE) _get_osfhandle(bd->fd)) ? 0 : -1;
|
||||||
#else
|
#else
|
||||||
@@ -153,10 +153,10 @@ int lfs_filebd_sync(const struct lfs_config *cfg) {
|
|||||||
#endif
|
#endif
|
||||||
if (err) {
|
if (err) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_sync -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_sync -> %d", 0);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS_FILEBD_TRACE("lfs_filebd_sync -> %d", 0);
|
LFS3_FILEBD_TRACE("lfs3_filebd_sync -> %d", 0);
|
||||||
return 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) 2022, The littlefs authors.
|
||||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
#include "lfs_util.h"
|
#include "lfs3_util.h"
|
||||||
|
|
||||||
// Only compile if user does not provide custom config
|
// Only compile if user does not provide custom config
|
||||||
#ifndef LFS_CONFIG
|
#ifndef LFS3_CONFIG
|
||||||
|
|
||||||
// Need lfs.h for error codes
|
// Need lfs3.h for error codes
|
||||||
// TODO should we actually move the error codes to lfs_util.h?
|
// TODO should we actually move the error codes to lfs3_util.h?
|
||||||
#include "lfs.h"
|
#include "lfs3.h"
|
||||||
|
|
||||||
|
|
||||||
// Convert to/from leb128 encoding
|
// 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;
|
uint8_t *data = buffer;
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
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?
|
// 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;
|
const uint8_t *data = buffer;
|
||||||
|
|
||||||
int32_t word_ = 0;
|
int32_t word_ = 0;
|
||||||
@@ -44,7 +44,7 @@ ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
|
|||||||
if (!(dat & 0x80)) {
|
if (!(dat & 0x80)) {
|
||||||
// did we overflow?
|
// did we overflow?
|
||||||
if ((word_ >> 7*i) != dat) {
|
if ((word_ >> 7*i) != dat) {
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS3_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
*word = word_;
|
*word = word_;
|
||||||
@@ -53,15 +53,15 @@ ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// truncated?
|
// truncated?
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS3_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// crc32c tables (see lfs_crc32c for more info)
|
// crc32c tables (see lfs3_crc32c for more info)
|
||||||
#if !defined(LFS_SMALLER_CRC32C) \
|
#if !defined(LFS3_SMALLER_CRC32C) \
|
||||||
&& !defined(LFS_FASTER_CRC32C) \
|
&& !defined(LFS3_FASTER_CRC32C) \
|
||||||
&& !defined(LFS_PMUL_CRC32C)
|
&& !defined(LFS3_PMUL_CRC32C)
|
||||||
static const uint32_t lfs_crc32c_table[16] = {
|
static const uint32_t lfs3_crc32c_table[16] = {
|
||||||
0x00000000, 0x105ec76f, 0x20bd8ede, 0x30e349b1,
|
0x00000000, 0x105ec76f, 0x20bd8ede, 0x30e349b1,
|
||||||
0x417b1dbc, 0x5125dad3, 0x61c69362, 0x7198540d,
|
0x417b1dbc, 0x5125dad3, 0x61c69362, 0x7198540d,
|
||||||
0x82f63b78, 0x92a8fc17, 0xa24bb5a6, 0xb21572c9,
|
0x82f63b78, 0x92a8fc17, 0xa24bb5a6, 0xb21572c9,
|
||||||
@@ -69,10 +69,10 @@ static const uint32_t lfs_crc32c_table[16] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LFS_FASTER_CRC32C) \
|
#if defined(LFS3_FASTER_CRC32C) \
|
||||||
&& !defined(LFS_SMALLER_CRC32C) \
|
&& !defined(LFS3_SMALLER_CRC32C) \
|
||||||
&& !defined(LFS_PMUL_CRC32C)
|
&& !defined(LFS3_PMUL_CRC32C)
|
||||||
static const uint32_t lfs_crc32c_table[256] = {
|
static const uint32_t lfs3_crc32c_table[256] = {
|
||||||
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
|
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
|
||||||
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
|
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
|
||||||
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
|
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
|
||||||
@@ -142,7 +142,7 @@ static const uint32_t lfs_crc32c_table[256] = {
|
|||||||
|
|
||||||
|
|
||||||
// Calculate crc32c incrementally
|
// 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
|
// init with 0xffffffff so prefixed zeros affect the crc
|
||||||
const uint8_t *buffer_ = buffer;
|
const uint8_t *buffer_ = buffer;
|
||||||
crc ^= 0xffffffff;
|
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
|
// PCLMULQDQ Instruction whitepaper is an excellent resource on this
|
||||||
// topic.
|
// topic.
|
||||||
//
|
//
|
||||||
#if defined(LFS_SMALLER_CRC32C) && !defined(LFS_PMUL_CRC32C)
|
#if defined(LFS3_SMALLER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
|
||||||
// naive reduce
|
// naive reduce
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
crc = crc ^ buffer_[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
|
// reduce via small table
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
crc = (crc >> 4) ^ lfs_crc32c_table[0xf & (crc ^ (buffer_[i] >> 0))];
|
crc = (crc >> 4) ^ lfs3_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] >> 4))];
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C)
|
#elif defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
|
||||||
// reduce via big table
|
// reduce via big table
|
||||||
for (size_t i = 0; i < size; i++) {
|
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
|
// reduce via Barret reduction
|
||||||
for (size_t i = 0; i < size;) {
|
for (size_t i = 0; i < size;) {
|
||||||
// align to 32-bits
|
// align to 32-bits
|
||||||
if ((uintptr_t)&buffer_[i] % sizeof(uint32_t) == 0
|
if ((uintptr_t)&buffer_[i] % sizeof(uint32_t) == 0
|
||||||
&& i+sizeof(uint32_t) < size) {
|
&& i+sizeof(uint32_t) < size) {
|
||||||
crc = crc ^ lfs_fromle32_(&buffer_[i]);
|
crc = crc ^ lfs3_fromle32_(&buffer_[i]);
|
||||||
crc = lfs_pmul(
|
crc = lfs3_pmul(
|
||||||
lfs_pmul(crc, 0xdea713f1),
|
lfs3_pmul(crc, 0xdea713f1),
|
||||||
0x82f63b78)
|
0x82f63b78)
|
||||||
>> 31;
|
>> 31;
|
||||||
i += 4;
|
i += 4;
|
||||||
} else {
|
} else {
|
||||||
crc = crc ^ buffer_[i];
|
crc = crc ^ buffer_[i];
|
||||||
crc = (crc >> 8)
|
crc = (crc >> 8)
|
||||||
^ (lfs_pmul(
|
^ (lfs3_pmul(
|
||||||
lfs_pmul(crc << 24, 0xdea713f1),
|
lfs3_pmul(crc << 24, 0xdea713f1),
|
||||||
0x82f63b78)
|
0x82f63b78)
|
||||||
>> 31);
|
>> 31);
|
||||||
i += 1;
|
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
|
// 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 in a crc32c ring involves polynomial
|
||||||
// multiplication modulo the crc32c polynomial to keep things
|
// multiplication modulo the crc32c polynomial to keep things
|
||||||
// finite:
|
// 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
|
// This gets a bit funky because crc32cs are little-endian, but
|
||||||
// fortunately pmul is symmetric. Though the result is awkwardly
|
// fortunately pmul is symmetric. Though the result is awkwardly
|
||||||
// 63-bits, so we need to shift by 1.
|
// 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
|
// We can accelerate our module with crc32c tables if present, these
|
||||||
// loops may look familiar.
|
// loops may look familiar.
|
||||||
#if defined(LFS_SMALLER_CRC32C) && !defined(LFS_PMUL_CRC32C)
|
#if defined(LFS3_SMALLER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
|
||||||
// naive reduce
|
// naive reduce
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
r = (r >> 1) ^ ((r & 1) ? 0x82f63b78 : 0);
|
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
|
// reduce via small table
|
||||||
for (int i = 0; i < 8; i++) {
|
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
|
// reduce via big table
|
||||||
for (int i = 0; i < 4; i++) {
|
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
|
// reduce via Barret reduction
|
||||||
r = (r >> 32)
|
r = (r >> 32)
|
||||||
^ (lfs_pmul(
|
^ (lfs3_pmul(
|
||||||
lfs_pmul(r, 0xdea713f1),
|
lfs3_pmul(r, 0xdea713f1),
|
||||||
0x82f63b78)
|
0x82f63b78)
|
||||||
>> 31);
|
>> 31);
|
||||||
#endif
|
#endif
|
||||||
+211
-211
@@ -1,93 +1,93 @@
|
|||||||
/*
|
/*
|
||||||
* lfs utility functions
|
* lfs3 utility functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2022, The littlefs authors.
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
#ifndef LFS_UTIL_H
|
#ifndef LFS3_UTIL_H
|
||||||
#define LFS_UTIL_H
|
#define LFS3_UTIL_H
|
||||||
|
|
||||||
// Users can override lfs_util.h with their own configuration by defining
|
// Users can override lfs3_util.h with their own configuration by defining
|
||||||
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
|
// 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
|
// 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 lfs_util.h
|
// provided by the config file. To start, I would suggest copying lfs3_util.h
|
||||||
// and modifying as needed.
|
// and modifying as needed.
|
||||||
#ifdef LFS_CONFIG
|
#ifdef LFS3_CONFIG
|
||||||
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
|
#define LFS3_STRINGIZE(x) LFS3_STRINGIZE2(x)
|
||||||
#define LFS_STRINGIZE2(x) #x
|
#define LFS3_STRINGIZE2(x) #x
|
||||||
#include LFS_STRINGIZE(LFS_CONFIG)
|
#include LFS3_STRINGIZE(LFS3_CONFIG)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
// Some convenient macro aliases
|
// 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
|
// LFS3_BIGGEST enables all opt-in features
|
||||||
#ifdef LFS_BIGGEST
|
#ifdef LFS3_BIGGEST
|
||||||
#ifndef LFS_REVDBG
|
#ifndef LFS3_REVDBG
|
||||||
#define LFS_REVDBG
|
#define LFS3_REVDBG
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_REVNOISE
|
#ifndef LFS3_REVNOISE
|
||||||
#define LFS_REVNOISE
|
#define LFS3_REVNOISE
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_CKPROGS
|
#ifndef LFS3_CKPROGS
|
||||||
#define LFS_CKPROGS
|
#define LFS3_CKPROGS
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_CKFETCHES
|
#ifndef LFS3_CKFETCHES
|
||||||
#define LFS_CKFETCHES
|
#define LFS3_CKFETCHES
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_CKMETAPARITY
|
#ifndef LFS3_CKMETAPARITY
|
||||||
#define LFS_CKMETAPARITY
|
#define LFS3_CKMETAPARITY
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_CKDATACKSUMREADS
|
#ifndef LFS3_CKDATACKSUMREADS
|
||||||
#define LFS_CKDATACKSUMREADS
|
#define LFS3_CKDATACKSUMREADS
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_GC
|
#ifndef LFS3_GC
|
||||||
#define LFS_GC
|
#define LFS3_GC
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// LFS_YES_* variants imply the relevant LFS_* macro
|
// LFS3_YES_* variants imply the relevant LFS3_* macro
|
||||||
#ifdef LFS_YES_RDONLY
|
#ifdef LFS3_YES_RDONLY
|
||||||
#define LFS_RDONLY
|
#define LFS3_RDONLY
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_REVDBG
|
#ifdef LFS3_YES_REVDBG
|
||||||
#define LFS_REVDBG
|
#define LFS3_REVDBG
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_REVNOISE
|
#ifdef LFS3_YES_REVNOISE
|
||||||
#define LFS_REVNOISE
|
#define LFS3_REVNOISE
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_CKPROGS
|
#ifdef LFS3_YES_CKPROGS
|
||||||
#define LFS_CKPROGS
|
#define LFS3_CKPROGS
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_CKFETCHES
|
#ifdef LFS3_YES_CKFETCHES
|
||||||
#define LFS_CKFETCHES
|
#define LFS3_CKFETCHES
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_CKMETAPARITY
|
#ifdef LFS3_YES_CKMETAPARITY
|
||||||
#define LFS_CKMETAPARITY
|
#define LFS3_CKMETAPARITY
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_CKDATACKSUMREADS
|
#ifdef LFS3_YES_CKDATACKSUMREADS
|
||||||
#define LFS_CKDATACKSUMREADS
|
#define LFS3_CKDATACKSUMREADS
|
||||||
#endif
|
#endif
|
||||||
#ifdef LFS_YES_GC
|
#ifdef LFS3_YES_GC
|
||||||
#define LFS_GC
|
#define LFS3_GC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// LFS_NO_LOG disables all logging macros
|
// LFS3_NO_LOG disables all logging macros
|
||||||
#ifdef LFS_NO_LOG
|
#ifdef LFS3_NO_LOG
|
||||||
#ifndef LFS_NO_DEBUG
|
#ifndef LFS3_NO_DEBUG
|
||||||
#define LFS_NO_DEBUG
|
#define LFS3_NO_DEBUG
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_NO_INFO
|
#ifndef LFS3_NO_INFO
|
||||||
#define LFS_NO_INFO
|
#define LFS3_NO_INFO
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_NO_WARN
|
#ifndef LFS3_NO_WARN
|
||||||
#define LFS_NO_WARN
|
#define LFS3_NO_WARN
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_NO_ERROR
|
#ifndef LFS3_NO_ERROR
|
||||||
#define LFS_NO_ERROR
|
#define LFS3_NO_ERROR
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -97,20 +97,20 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#ifndef LFS_NO_STRINGH
|
#ifndef LFS3_NO_STRINGH
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_NO_MALLOC
|
#ifndef LFS3_NO_MALLOC
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef LFS_NO_ASSERT
|
#ifndef LFS3_NO_ASSERT
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
#if !defined(LFS_NO_DEBUG) || \
|
#if !defined(LFS3_NO_DEBUG) || \
|
||||||
!defined(LFS_NO_INFO) || \
|
!defined(LFS3_NO_INFO) || \
|
||||||
!defined(LFS_NO_WARN) || \
|
!defined(LFS3_NO_WARN) || \
|
||||||
!defined(LFS_NO_ERROR) || \
|
!defined(LFS3_NO_ERROR) || \
|
||||||
defined(LFS_YES_TRACE)
|
defined(LFS3_YES_TRACE)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -120,139 +120,139 @@
|
|||||||
// code footprint
|
// code footprint
|
||||||
|
|
||||||
// Logging functions
|
// Logging functions
|
||||||
#ifndef LFS_TRACE
|
#ifndef LFS3_TRACE
|
||||||
#ifdef LFS_YES_TRACE
|
#ifdef LFS3_YES_TRACE
|
||||||
#define LFS_TRACE_(fmt, ...) \
|
#define LFS3_TRACE_(fmt, ...) \
|
||||||
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
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
|
#else
|
||||||
#define LFS_TRACE(...)
|
#define LFS3_TRACE(...)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_DEBUG
|
#ifndef LFS3_DEBUG
|
||||||
#ifndef LFS_NO_DEBUG
|
#ifndef LFS3_NO_DEBUG
|
||||||
#define LFS_DEBUG_(fmt, ...) \
|
#define LFS3_DEBUG_(fmt, ...) \
|
||||||
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
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
|
#else
|
||||||
#define LFS_DEBUG(...)
|
#define LFS3_DEBUG(...)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_INFO
|
#ifndef LFS3_INFO
|
||||||
#ifndef LFS_NO_INFO
|
#ifndef LFS3_NO_INFO
|
||||||
#define LFS_INFO_(fmt, ...) \
|
#define LFS3_INFO_(fmt, ...) \
|
||||||
printf("%s:%d:info: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
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
|
#else
|
||||||
#define LFS_INFO(...)
|
#define LFS3_INFO(...)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_WARN
|
#ifndef LFS3_WARN
|
||||||
#ifndef LFS_NO_WARN
|
#ifndef LFS3_NO_WARN
|
||||||
#define LFS_WARN_(fmt, ...) \
|
#define LFS3_WARN_(fmt, ...) \
|
||||||
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
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
|
#else
|
||||||
#define LFS_WARN(...)
|
#define LFS3_WARN(...)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_ERROR
|
#ifndef LFS3_ERROR
|
||||||
#ifndef LFS_NO_ERROR
|
#ifndef LFS3_NO_ERROR
|
||||||
#define LFS_ERROR_(fmt, ...) \
|
#define LFS3_ERROR_(fmt, ...) \
|
||||||
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
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
|
#else
|
||||||
#define LFS_ERROR(...)
|
#define LFS3_ERROR(...)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Runtime assertions
|
// Runtime assertions
|
||||||
#ifndef LFS_ASSERT
|
#ifndef LFS3_ASSERT
|
||||||
#ifndef LFS_NO_ASSERT
|
#ifndef LFS3_NO_ASSERT
|
||||||
#define LFS_ASSERT(test) assert(test)
|
#define LFS3_ASSERT(test) assert(test)
|
||||||
#else
|
#else
|
||||||
#define LFS_ASSERT(test)
|
#define LFS3_ASSERT(test)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_UNREACHABLE
|
#ifndef LFS3_UNREACHABLE
|
||||||
#ifndef LFS_NO_ASSERT
|
#ifndef LFS3_NO_ASSERT
|
||||||
#define LFS_UNREACHABLE() LFS_ASSERT(false)
|
#define LFS3_UNREACHABLE() LFS3_ASSERT(false)
|
||||||
#elif !defined(LFS_NO_BUILTINS)
|
#elif !defined(LFS3_NO_BUILTINS)
|
||||||
#define LFS_UNREACHABLE() __builtin_unreachable()
|
#define LFS3_UNREACHABLE() __builtin_unreachable()
|
||||||
#else
|
#else
|
||||||
#define LFS_UNREACHABLE()
|
#define LFS3_UNREACHABLE()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Some ifdef conveniences
|
// Some ifdef conveniences
|
||||||
#ifdef LFS_REVDBG
|
#ifdef LFS3_REVDBG
|
||||||
#define LFS_IFDEF_REVDBG(a, b) (a)
|
#define LFS3_IFDEF_REVDBG(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_REVDBG(a, b) (b)
|
#define LFS3_IFDEF_REVDBG(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LFS_REVNOISE
|
#ifdef LFS3_REVNOISE
|
||||||
#define LFS_IFDEF_REVNOISE(a, b) (a)
|
#define LFS3_IFDEF_REVNOISE(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_REVNOISE(a, b) (b)
|
#define LFS3_IFDEF_REVNOISE(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LFS_CKPROGS
|
#ifdef LFS3_CKPROGS
|
||||||
#define LFS_IFDEF_CKPROGS(a, b) (a)
|
#define LFS3_IFDEF_CKPROGS(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_CKPROGS(a, b) (b)
|
#define LFS3_IFDEF_CKPROGS(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LFS_CKFETCHES
|
#ifdef LFS3_CKFETCHES
|
||||||
#define LFS_IFDEF_CKFETCHES(a, b) (a)
|
#define LFS3_IFDEF_CKFETCHES(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_CKFETCHES(a, b) (b)
|
#define LFS3_IFDEF_CKFETCHES(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LFS_CKMETAPARITY
|
#ifdef LFS3_CKMETAPARITY
|
||||||
#define LFS_IFDEF_CKMETAPARITY(a, b) (a)
|
#define LFS3_IFDEF_CKMETAPARITY(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_CKMETAPARITY(a, b) (b)
|
#define LFS3_IFDEF_CKMETAPARITY(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LFS_CKDATACKSUMREADS
|
#ifdef LFS3_CKDATACKSUMREADS
|
||||||
#define LFS_IFDEF_CKDATACKSUMREADS(a, b) (a)
|
#define LFS3_IFDEF_CKDATACKSUMREADS(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_CKDATACKSUMREADS(a, b) (b)
|
#define LFS3_IFDEF_CKDATACKSUMREADS(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LFS_GC
|
#ifdef LFS3_GC
|
||||||
#define LFS_IFDEF_GC(a, b) (a)
|
#define LFS3_IFDEF_GC(a, b) (a)
|
||||||
#else
|
#else
|
||||||
#define LFS_IFDEF_GC(a, b) (b)
|
#define LFS3_IFDEF_GC(a, b) (b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Some function attributes, no way around these
|
// Some function attributes, no way around these
|
||||||
|
|
||||||
// Force a function to be inlined
|
// Force a function to be inlined
|
||||||
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
|
#if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
|
||||||
#define LFS_FORCEINLINE __attribute__((always_inline))
|
#define LFS3_FORCEINLINE __attribute__((always_inline))
|
||||||
#else
|
#else
|
||||||
#define LFS_FORCEINLINE
|
#define LFS3_FORCEINLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Force a function to _not_ be inlined
|
// Force a function to _not_ be inlined
|
||||||
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
|
#if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
|
||||||
#define LFS_NOINLINE __attribute__((noinline))
|
#define LFS3_NOINLINE __attribute__((noinline))
|
||||||
#else
|
#else
|
||||||
#define LFS_NOINLINE
|
#define LFS3_NOINLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Builtin functions, these may be replaced by more efficient
|
// 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
|
// expensive basic C implementation for debugging purposes
|
||||||
//
|
//
|
||||||
// Most of the backup implementations are based on the infamous Bit
|
// Most of the backup implementations are based on the infamous Bit
|
||||||
@@ -261,33 +261,33 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Compile time min/max
|
// Compile time min/max
|
||||||
#define LFS_MIN(a, b) ((a < b) ? a : b)
|
#define LFS3_MIN(a, b) ((a < b) ? a : b)
|
||||||
#define LFS_MAX(a, b) ((a > b) ? a : b)
|
#define LFS3_MAX(a, b) ((a > b) ? a : b)
|
||||||
|
|
||||||
// Min/max functions for unsigned 32-bit numbers
|
// 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;
|
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;
|
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;
|
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;
|
return (a > b) ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Absolute value of signed numbers
|
// 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;
|
return (a < 0) ? -a : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap two variables
|
// Swap two variables
|
||||||
#define LFS_SWAP(_t, _a, _b) \
|
#define LFS3_SWAP(_t, _a, _b) \
|
||||||
do { \
|
do { \
|
||||||
_t *a = _a; \
|
_t *a = _a; \
|
||||||
_t *b = _b; \
|
_t *b = _b; \
|
||||||
@@ -297,22 +297,22 @@ static inline int32_t lfs_abs(int32_t a) {
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Align to nearest multiple of a size
|
// 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);
|
return a - (a % alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) {
|
static inline uint32_t lfs3_alignup(uint32_t a, uint32_t alignment) {
|
||||||
return lfs_aligndown(a + alignment-1, alignment);
|
return lfs3_aligndown(a + alignment-1, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the smallest power of 2 greater than or equal to a
|
// 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
|
// __builtin_clz of zero is undefined, so treat both 0 and 1 specially
|
||||||
if (a <= 1) {
|
if (a <= 1) {
|
||||||
return a;
|
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);
|
return 32 - __builtin_clz(a-1);
|
||||||
#else
|
#else
|
||||||
uint32_t r = 0;
|
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
|
// Count the number of trailing binary zeros in a
|
||||||
// lfs_ctz(0) may be undefined
|
// lfs3_ctz(0) may be undefined
|
||||||
static inline uint32_t lfs_ctz(uint32_t a) {
|
static inline uint32_t lfs3_ctz(uint32_t a) {
|
||||||
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__)
|
#if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
|
||||||
return __builtin_ctz(a);
|
return __builtin_ctz(a);
|
||||||
#else
|
#else
|
||||||
return lfs_nlog2((a & -a) + 1) - 1;
|
return lfs3_nlog2((a & -a) + 1) - 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the number of binary ones in a
|
// Count the number of binary ones in a
|
||||||
static inline uint32_t lfs_popc(uint32_t a) {
|
static inline uint32_t lfs3_popc(uint32_t a) {
|
||||||
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
|
#if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||||
return __builtin_popcount(a);
|
return __builtin_popcount(a);
|
||||||
#else
|
#else
|
||||||
a = a - ((a >> 1) & 0x55555555);
|
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
|
// Returns true if there is an odd number of binary ones in a
|
||||||
static inline bool lfs_parity(uint32_t a) {
|
static inline bool lfs3_parity(uint32_t a) {
|
||||||
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
|
#if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||||
return __builtin_parity(a);
|
return __builtin_parity(a);
|
||||||
#else
|
#else
|
||||||
a ^= a >> 16;
|
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
|
// Find the sequence comparison of a and b, this is the distance
|
||||||
// between a and b ignoring overflow
|
// 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);
|
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
|
// 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
|
// a and b as binary polynomials, xor is polynomial addition and pmul is
|
||||||
// polynomial multiplication.
|
// 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 r = 0;
|
||||||
uint64_t a_ = a;
|
uint64_t a_ = a;
|
||||||
while (b) {
|
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
|
// 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)[0] = word >> 0;
|
||||||
((uint8_t*)buffer)[1] = word >> 8;
|
((uint8_t*)buffer)[1] = word >> 8;
|
||||||
((uint8_t*)buffer)[2] = word >> 16;
|
((uint8_t*)buffer)[2] = word >> 16;
|
||||||
((uint8_t*)buffer)[3] = word >> 24;
|
((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)
|
return (((uint8_t*)buffer)[0] << 0)
|
||||||
| (((uint8_t*)buffer)[1] << 8)
|
| (((uint8_t*)buffer)[1] << 8)
|
||||||
| (((uint8_t*)buffer)[2] << 16)
|
| (((uint8_t*)buffer)[2] << 16)
|
||||||
@@ -401,19 +401,19 @@ static inline uint32_t lfs_fromle32(const void *buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert to/from leb128 encoding
|
// Convert to/from leb128 encoding
|
||||||
// TODO should we really be using ssize_t here and not lfs_ssize_t?
|
// TODO should we really be using ssize_t here and not lfs3_ssize_t?
|
||||||
ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size);
|
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
|
// Compare n bytes of memory
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_memcmp memcmp
|
#define lfs3_memcmp memcmp
|
||||||
#elif !defined(LFS_NO_BUILTINS)
|
#elif !defined(LFS3_NO_BUILTINS)
|
||||||
#define lfs_memcmp __builtin_memcmp
|
#define lfs3_memcmp __builtin_memcmp
|
||||||
#else
|
#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 *a_ = a;
|
||||||
const uint8_t *b_ = b;
|
const uint8_t *b_ = b;
|
||||||
for (size_t i = 0; i < size; i++) {
|
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
|
#endif
|
||||||
|
|
||||||
// Copy n bytes from src to dst, src and dst must not overlap
|
// Copy n bytes from src to dst, src and dst must not overlap
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_memcpy memcpy
|
#define lfs3_memcpy memcpy
|
||||||
#elif !defined(LFS_NO_BUILTINS)
|
#elif !defined(LFS3_NO_BUILTINS)
|
||||||
#define lfs_memcpy __builtin_memcpy
|
#define lfs3_memcpy __builtin_memcpy
|
||||||
#else
|
#else
|
||||||
static inline void *lfs_memcpy(
|
static inline void *lfs3_memcpy(
|
||||||
void *restrict dst, const void *restrict src, size_t size) {
|
void *restrict dst, const void *restrict src, size_t size) {
|
||||||
uint8_t *dst_ = dst;
|
uint8_t *dst_ = dst;
|
||||||
const uint8_t *src_ = src;
|
const uint8_t *src_ = src;
|
||||||
@@ -445,12 +445,12 @@ static inline void *lfs_memcpy(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copy n bytes from src to dst, src and dst may overlap
|
// Copy n bytes from src to dst, src and dst may overlap
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_memmove memmove
|
#define lfs3_memmove memmove
|
||||||
#elif !defined(LFS_NO_BUILTINS)
|
#elif !defined(LFS3_NO_BUILTINS)
|
||||||
#define lfs_memmove __builtin_memmove
|
#define lfs3_memmove __builtin_memmove
|
||||||
#else
|
#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;
|
uint8_t *dst_ = dst;
|
||||||
const uint8_t *src_ = src;
|
const uint8_t *src_ = src;
|
||||||
if (dst_ < src_) {
|
if (dst_ < src_) {
|
||||||
@@ -468,12 +468,12 @@ static inline void *lfs_memmove(void *dst, const void *src, size_t size) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set n bytes to c
|
// Set n bytes to c
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_memset memset
|
#define lfs3_memset memset
|
||||||
#elif !defined(LFS_NO_BUILTINS)
|
#elif !defined(LFS3_NO_BUILTINS)
|
||||||
#define lfs_memset __builtin_memset
|
#define lfs3_memset __builtin_memset
|
||||||
#else
|
#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;
|
uint8_t *dst_ = dst;
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
dst_[i] = c;
|
dst_[i] = c;
|
||||||
@@ -484,10 +484,10 @@ static inline void *lfs_memset(void *dst, int c, size_t size) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find the first occurrence of c or NULL
|
// Find the first occurrence of c or NULL
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_memchr memchr
|
#define lfs3_memchr memchr
|
||||||
#else
|
#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;
|
const uint8_t *a_ = a;
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
if (a_[i] == c) {
|
if (a_[i] == c) {
|
||||||
@@ -500,7 +500,7 @@ static inline void *lfs_memchr(const void *a, int c, size_t size) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find the first occurrence of anything not c or NULL
|
// 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;
|
const uint8_t *a_ = a;
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
if (a_[i] != c) {
|
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
|
// 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;
|
const uint8_t *a_ = a;
|
||||||
while (size > 0 && a_[size-1] == 0) {
|
while (size > 0 && a_[size-1] == 0) {
|
||||||
size -= 1;
|
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
|
// 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) {
|
void *restrict a, const void *restrict b, size_t size) {
|
||||||
uint8_t *a_ = a;
|
uint8_t *a_ = a;
|
||||||
const uint8_t *b_ = b;
|
const uint8_t *b_ = b;
|
||||||
@@ -535,10 +535,10 @@ static inline void *lfs_memxor(
|
|||||||
|
|
||||||
|
|
||||||
// Find the length of a null-terminated string
|
// Find the length of a null-terminated string
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_strlen strlen
|
#define lfs3_strlen strlen
|
||||||
#else
|
#else
|
||||||
static inline size_t lfs_strlen(const char *a) {
|
static inline size_t lfs3_strlen(const char *a) {
|
||||||
const char *a_ = a;
|
const char *a_ = a;
|
||||||
while (*a_) {
|
while (*a_) {
|
||||||
a_++;
|
a_++;
|
||||||
@@ -549,10 +549,10 @@ static inline size_t lfs_strlen(const char *a) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compare two null-terminated strings
|
// Compare two null-terminated strings
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_strcmp strcmp
|
#define lfs3_strcmp strcmp
|
||||||
#else
|
#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) {
|
while (*a && *a == *b) {
|
||||||
a++;
|
a++;
|
||||||
b++;
|
b++;
|
||||||
@@ -563,10 +563,10 @@ static inline int lfs_strcmp(const char *a, const char *b) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copy a null-terminated string from src to dst
|
// Copy a null-terminated string from src to dst
|
||||||
#if !defined(LFS_NO_STRINGH)
|
#if !defined(LFS3_NO_STRINGH)
|
||||||
#define lfs_strcpy strcpy
|
#define lfs3_strcpy strcpy
|
||||||
#else
|
#else
|
||||||
static inline char *lfs_strcpy(
|
static inline char *lfs3_strcpy(
|
||||||
char *restrict dst, const char *restrict src) {
|
char *restrict dst, const char *restrict src) {
|
||||||
char *dst_ = dst;
|
char *dst_ = dst;
|
||||||
while (*src) {
|
while (*src) {
|
||||||
@@ -581,10 +581,10 @@ static inline char *lfs_strcpy(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find first occurrence of c or NULL
|
// Find first occurrence of c or NULL
|
||||||
#ifndef LFS_NO_STRINGH
|
#ifndef LFS3_NO_STRINGH
|
||||||
#define lfs_strchr strchr
|
#define lfs3_strchr strchr
|
||||||
#else
|
#else
|
||||||
static inline char *lfs_strchr(const char *a, int c) {
|
static inline char *lfs3_strchr(const char *a, int c) {
|
||||||
while (*a) {
|
while (*a) {
|
||||||
if (*a == c) {
|
if (*a == c) {
|
||||||
return (char*)a;
|
return (char*)a;
|
||||||
@@ -598,7 +598,7 @@ static inline char *lfs_strchr(const char *a, int c) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find first occurrence of anything not c or NULL
|
// 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) {
|
while (*a) {
|
||||||
if (*a != c) {
|
if (*a != c) {
|
||||||
return (char*)a;
|
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
|
// Find length of a that does not contain any char in cs
|
||||||
#ifndef LFS_NO_STRINGH
|
#ifndef LFS3_NO_STRINGH
|
||||||
#define lfs_strspn strspn
|
#define lfs3_strspn strspn
|
||||||
#else
|
#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;
|
const char *a_ = a;
|
||||||
while (*a_) {
|
while (*a_) {
|
||||||
const char *cs_ = cs;
|
const char *cs_ = cs;
|
||||||
@@ -633,10 +633,10 @@ static inline size_t lfs_strspn(const char *a, const char *cs) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find length of a that only contains chars in cs
|
// Find length of a that only contains chars in cs
|
||||||
#ifndef LFS_NO_STRINGH
|
#ifndef LFS3_NO_STRINGH
|
||||||
#define lfs_strcspn strcspn
|
#define lfs3_strcspn strcspn
|
||||||
#else
|
#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;
|
const char *a_ = a;
|
||||||
while (*a_) {
|
while (*a_) {
|
||||||
const char *cs_ = cs;
|
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
|
// Odd-parity and even-parity zeros in our crc32c ring
|
||||||
#define LFS_CRC32C_ODDZERO 0xfca42daf
|
#define LFS3_CRC32C_ODDZERO 0xfca42daf
|
||||||
#define LFS_CRC32C_EVENZERO 0x00000000
|
#define LFS3_CRC32C_EVENZERO 0x00000000
|
||||||
|
|
||||||
// Calculate crc32c incrementally
|
// Calculate crc32c incrementally
|
||||||
//
|
//
|
||||||
@@ -665,32 +665,32 @@ static inline size_t lfs_strcspn(const char *a, const char *cs) {
|
|||||||
// init = 0xffffffff
|
// init = 0xffffffff
|
||||||
// fini = 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
|
// 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
|
// Find the cube of a crc32c in the crc32c ring
|
||||||
static inline uint32_t lfs_crc32c_cube(uint32_t a) {
|
static inline uint32_t lfs3_crc32c_cube(uint32_t a) {
|
||||||
return lfs_crc32c_mul(lfs_crc32c_mul(a, a), a);
|
return lfs3_crc32c_mul(lfs3_crc32c_mul(a, a), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Allocate memory, only used if buffers are not provided to littlefs
|
// Allocate memory, only used if buffers are not provided to littlefs
|
||||||
#ifndef LFS_NO_MALLOC
|
#ifndef LFS3_NO_MALLOC
|
||||||
#define lfs_malloc malloc
|
#define lfs3_malloc malloc
|
||||||
#else
|
#else
|
||||||
static inline void *lfs_malloc(size_t size) {
|
static inline void *lfs3_malloc(size_t size) {
|
||||||
(void)size;
|
(void)size;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Deallocate memory, only used if buffers are not provided to littlefs
|
// Deallocate memory, only used if buffers are not provided to littlefs
|
||||||
#ifndef LFS_NO_MALLOC
|
#ifndef LFS3_NO_MALLOC
|
||||||
#define lfs_free free
|
#define lfs3_free free
|
||||||
#else
|
#else
|
||||||
static inline void lfs_free(void *p) {
|
static inline void lfs3_free(void *p) {
|
||||||
(void)p;
|
(void)p;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
+25
-25
@@ -9,7 +9,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "runners/bench_runner.h"
|
#include "runners/bench_runner.h"
|
||||||
#include "bd/lfs_emubd.h"
|
#include "bd/lfs3_emubd.h"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -439,9 +439,9 @@ FILE *bench_trace_file = NULL;
|
|||||||
uint32_t bench_trace_cycles = 0;
|
uint32_t bench_trace_cycles = 0;
|
||||||
uint64_t bench_trace_time = 0;
|
uint64_t bench_trace_time = 0;
|
||||||
uint64_t bench_trace_open_time = 0;
|
uint64_t bench_trace_open_time = 0;
|
||||||
lfs_emubd_sleep_t bench_read_sleep = 0.0;
|
lfs3_emubd_sleep_t bench_read_sleep = 0.0;
|
||||||
lfs_emubd_sleep_t bench_prog_sleep = 0.0;
|
lfs3_emubd_sleep_t bench_prog_sleep = 0.0;
|
||||||
lfs_emubd_sleep_t bench_erase_sleep = 0.0;
|
lfs3_emubd_sleep_t bench_erase_sleep = 0.0;
|
||||||
|
|
||||||
// this determines both the backtrace buffer and the trace printf buffer, if
|
// this determines both the backtrace buffer and the trace printf buffer, if
|
||||||
// trace ends up interleaved or truncated this may need to be increased
|
// 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 {
|
typedef struct bench_record {
|
||||||
const char *m;
|
const char *m;
|
||||||
uintmax_t n;
|
uintmax_t n;
|
||||||
lfs_emubd_io_t last_readed;
|
lfs3_emubd_io_t last_readed;
|
||||||
lfs_emubd_io_t last_proged;
|
lfs3_emubd_io_t last_proged;
|
||||||
lfs_emubd_io_t last_erased;
|
lfs3_emubd_io_t last_erased;
|
||||||
} bench_record_t;
|
} bench_record_t;
|
||||||
|
|
||||||
static struct lfs_config *bench_cfg = NULL;
|
static struct lfs3_config *bench_cfg = NULL;
|
||||||
static bench_record_t *bench_records;
|
static bench_record_t *bench_records;
|
||||||
size_t bench_record_count;
|
size_t bench_record_count;
|
||||||
size_t bench_record_capacity;
|
size_t bench_record_capacity;
|
||||||
|
|
||||||
void bench_reset(struct lfs_config *cfg) {
|
void bench_reset(struct lfs3_config *cfg) {
|
||||||
bench_cfg = cfg;
|
bench_cfg = cfg;
|
||||||
bench_record_count = 0;
|
bench_record_count = 0;
|
||||||
}
|
}
|
||||||
@@ -625,11 +625,11 @@ void bench_reset(struct lfs_config *cfg) {
|
|||||||
void bench_start(const char *m, uintmax_t n) {
|
void bench_start(const char *m, uintmax_t n) {
|
||||||
// measure current read/prog/erase
|
// measure current read/prog/erase
|
||||||
assert(bench_cfg);
|
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);
|
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);
|
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);
|
assert(erased >= 0);
|
||||||
|
|
||||||
// allocate a new record
|
// allocate a new record
|
||||||
@@ -648,11 +648,11 @@ void bench_start(const char *m, uintmax_t n) {
|
|||||||
void bench_stop(const char *m) {
|
void bench_stop(const char *m) {
|
||||||
// measure current read/prog/erase
|
// measure current read/prog/erase
|
||||||
assert(bench_cfg);
|
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);
|
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);
|
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);
|
assert(erased >= 0);
|
||||||
|
|
||||||
// find our record
|
// find our record
|
||||||
@@ -1335,18 +1335,18 @@ void perm_run(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create block device and configuration
|
// create block device and configuration
|
||||||
lfs_emubd_t bd;
|
lfs3_emubd_t bd;
|
||||||
|
|
||||||
struct lfs_config cfg = {
|
struct lfs3_config cfg = {
|
||||||
.context = &bd,
|
.context = &bd,
|
||||||
.read = lfs_emubd_read,
|
.read = lfs3_emubd_read,
|
||||||
.prog = lfs_emubd_prog,
|
.prog = lfs3_emubd_prog,
|
||||||
.erase = lfs_emubd_erase,
|
.erase = lfs3_emubd_erase,
|
||||||
.sync = lfs_emubd_sync,
|
.sync = lfs3_emubd_sync,
|
||||||
BENCH_CFG
|
BENCH_CFG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_emubd_config bdcfg = {
|
struct lfs3_emubd_config bdcfg = {
|
||||||
.disk_path = bench_disk_path,
|
.disk_path = bench_disk_path,
|
||||||
.read_sleep = bench_read_sleep,
|
.read_sleep = bench_read_sleep,
|
||||||
.prog_sleep = bench_prog_sleep,
|
.prog_sleep = bench_prog_sleep,
|
||||||
@@ -1354,7 +1354,7 @@ void perm_run(
|
|||||||
BENCH_BDCFG
|
BENCH_BDCFG
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_emubd_createcfg(&cfg, bench_disk_path, &bdcfg);
|
int err = lfs3_emubd_createcfg(&cfg, bench_disk_path, &bdcfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not create block device: %d\n", err);
|
fprintf(stderr, "error: could not create block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1373,7 +1373,7 @@ void perm_run(
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
err = lfs_emubd_destroy(&cfg);
|
err = lfs3_emubd_destroy(&cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1920,7 +1920,7 @@ getopt_done: ;
|
|||||||
|
|
||||||
if (d >= define_count) {
|
if (d >= define_count) {
|
||||||
// align to power of two to avoid any superlinear growth
|
// 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,
|
defines = realloc(defines,
|
||||||
ncount*sizeof(bench_define_t));
|
ncount*sizeof(bench_define_t));
|
||||||
memset(defines+define_count, 0,
|
memset(defines+define_count, 0,
|
||||||
|
|||||||
+13
-13
@@ -8,16 +8,16 @@
|
|||||||
#define BENCH_RUNNER_H
|
#define BENCH_RUNNER_H
|
||||||
|
|
||||||
|
|
||||||
// override LFS_TRACE
|
// override LFS3_TRACE
|
||||||
void bench_trace(const char *fmt, ...);
|
void bench_trace(const char *fmt, ...);
|
||||||
|
|
||||||
#define LFS_TRACE_(fmt, ...) \
|
#define LFS3_TRACE_(fmt, ...) \
|
||||||
bench_trace("%s:%d:trace: " fmt "%s\n", \
|
bench_trace("%s:%d:trace: " fmt "%s\n", \
|
||||||
__FILE__, \
|
__FILE__, \
|
||||||
__LINE__, \
|
__LINE__, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
#define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
|
||||||
#define LFS_EMUBD_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
#define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
|
||||||
|
|
||||||
// BENCH_START/BENCH_STOP macros measure readed/proged/erased bytes
|
// BENCH_START/BENCH_STOP macros measure readed/proged/erased bytes
|
||||||
// through emubd
|
// 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
|
// note these are indirectly included in any generated files
|
||||||
#include "bd/lfs_emubd.h"
|
#include "bd/lfs3_emubd.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// give source a chance to define feature macros
|
// 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
|
// generated bench configurations
|
||||||
struct lfs_config;
|
struct lfs3_config;
|
||||||
|
|
||||||
enum bench_flags {
|
enum bench_flags {
|
||||||
BENCH_INTERNAL = 0x1,
|
BENCH_INTERNAL = 0x1,
|
||||||
@@ -69,7 +69,7 @@ struct bench_case {
|
|||||||
size_t permutations;
|
size_t permutations;
|
||||||
|
|
||||||
bool (*if_)(void);
|
bool (*if_)(void);
|
||||||
void (*run)(struct lfs_config *cfg);
|
void (*run)(struct lfs3_config *cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bench_suite {
|
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(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \
|
||||||
BENCH_DEFINE(DISK_SIZE, 1024*1024 ) \
|
BENCH_DEFINE(DISK_SIZE, 1024*1024 ) \
|
||||||
BENCH_DEFINE(BLOCK_RECYCLES, -1 ) \
|
BENCH_DEFINE(BLOCK_RECYCLES, -1 ) \
|
||||||
BENCH_DEFINE(RCACHE_SIZE, LFS_MAX(16, READ_SIZE) ) \
|
BENCH_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) ) \
|
||||||
BENCH_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
|
BENCH_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \
|
||||||
BENCH_DEFINE(FILE_CACHE_SIZE, 16 ) \
|
BENCH_DEFINE(FILE_CACHE_SIZE, 16 ) \
|
||||||
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
||||||
BENCH_DEFINE(GC_FLAGS, 0 ) \
|
BENCH_DEFINE(GC_FLAGS, 0 ) \
|
||||||
BENCH_DEFINE(GC_STEPS, 0 ) \
|
BENCH_DEFINE(GC_STEPS, 0 ) \
|
||||||
BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
||||||
BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
|
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(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
|
||||||
BENCH_DEFINE(FRAGMENT_THRESH, -1 ) \
|
BENCH_DEFINE(FRAGMENT_THRESH, -1 ) \
|
||||||
BENCH_DEFINE(ERASE_VALUE, 0xff ) \
|
BENCH_DEFINE(ERASE_VALUE, 0xff ) \
|
||||||
BENCH_DEFINE(ERASE_CYCLES, 0 ) \
|
BENCH_DEFINE(ERASE_CYCLES, 0 ) \
|
||||||
BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS_EMUBD_BADBLOCK_PROGERROR ) \
|
BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
|
||||||
BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS_EMUBD_POWERLOSS_ATOMIC ) \
|
BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) \
|
||||||
BENCH_DEFINE(EMUBD_SEED, 0 )
|
BENCH_DEFINE(EMUBD_SEED, 0 )
|
||||||
|
|
||||||
// declare defines as global intmax_ts
|
// 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, \
|
.crystal_thresh = CRYSTAL_THRESH, \
|
||||||
.fragment_thresh = FRAGMENT_THRESH,
|
.fragment_thresh = FRAGMENT_THRESH,
|
||||||
|
|
||||||
#ifdef LFS_GC
|
#ifdef LFS3_GC
|
||||||
#define BENCH_GC_CFG \
|
#define BENCH_GC_CFG \
|
||||||
.gc_flags = GC_FLAGS, \
|
.gc_flags = GC_FLAGS, \
|
||||||
.gc_steps = GC_STEPS,
|
.gc_steps = GC_STEPS,
|
||||||
|
|||||||
+76
-76
@@ -9,7 +9,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "runners/test_runner.h"
|
#include "runners/test_runner.h"
|
||||||
#include "bd/lfs_emubd.h"
|
#include "bd/lfs3_emubd.h"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -117,7 +117,7 @@ typedef struct test_powerloss {
|
|||||||
const struct test_powerloss *powerloss,
|
const struct test_powerloss *powerloss,
|
||||||
const struct test_suite *suite,
|
const struct test_suite *suite,
|
||||||
const struct test_case *case_);
|
const struct test_case *case_);
|
||||||
const lfs_emubd_powercycles_t *cycles;
|
const lfs3_emubd_powercycles_t *cycles;
|
||||||
size_t cycle_count;
|
size_t cycle_count;
|
||||||
} test_powerloss_t;
|
} test_powerloss_t;
|
||||||
|
|
||||||
@@ -450,9 +450,9 @@ FILE *test_trace_file = NULL;
|
|||||||
uint32_t test_trace_cycles = 0;
|
uint32_t test_trace_cycles = 0;
|
||||||
uint64_t test_trace_time = 0;
|
uint64_t test_trace_time = 0;
|
||||||
uint64_t test_trace_open_time = 0;
|
uint64_t test_trace_open_time = 0;
|
||||||
lfs_emubd_sleep_t test_read_sleep = 0.0;
|
lfs3_emubd_sleep_t test_read_sleep = 0.0;
|
||||||
lfs_emubd_sleep_t test_prog_sleep = 0.0;
|
lfs3_emubd_sleep_t test_prog_sleep = 0.0;
|
||||||
lfs_emubd_sleep_t test_erase_sleep = 0.0;
|
lfs3_emubd_sleep_t test_erase_sleep = 0.0;
|
||||||
|
|
||||||
volatile size_t TEST_PLS = 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(
|
static void perm_printid(
|
||||||
const struct test_suite *suite,
|
const struct test_suite *suite,
|
||||||
const struct test_case *case_,
|
const struct test_case *case_,
|
||||||
const lfs_emubd_powercycles_t *cycles,
|
const lfs3_emubd_powercycles_t *cycles,
|
||||||
size_t cycle_count) {
|
size_t cycle_count) {
|
||||||
(void)suite;
|
(void)suite;
|
||||||
// case[:permutation[:powercycles]]
|
// case[:permutation[:powercycles]]
|
||||||
@@ -1299,18 +1299,18 @@ static void run_powerloss_none(
|
|||||||
(void)powerloss;
|
(void)powerloss;
|
||||||
|
|
||||||
// create block device and configuration
|
// create block device and configuration
|
||||||
lfs_emubd_t bd;
|
lfs3_emubd_t bd;
|
||||||
|
|
||||||
struct lfs_config cfg = {
|
struct lfs3_config cfg = {
|
||||||
.context = &bd,
|
.context = &bd,
|
||||||
.read = lfs_emubd_read,
|
.read = lfs3_emubd_read,
|
||||||
.prog = lfs_emubd_prog,
|
.prog = lfs3_emubd_prog,
|
||||||
.erase = lfs_emubd_erase,
|
.erase = lfs3_emubd_erase,
|
||||||
.sync = lfs_emubd_sync,
|
.sync = lfs3_emubd_sync,
|
||||||
TEST_CFG
|
TEST_CFG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_emubd_config bdcfg = {
|
struct lfs3_emubd_config bdcfg = {
|
||||||
.disk_path = test_disk_path,
|
.disk_path = test_disk_path,
|
||||||
.read_sleep = test_read_sleep,
|
.read_sleep = test_read_sleep,
|
||||||
.prog_sleep = test_prog_sleep,
|
.prog_sleep = test_prog_sleep,
|
||||||
@@ -1318,7 +1318,7 @@ static void run_powerloss_none(
|
|||||||
TEST_BDCFG
|
TEST_BDCFG
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not create block device: %d\n", err);
|
fprintf(stderr, "error: could not create block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1339,7 +1339,7 @@ static void run_powerloss_none(
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
err = lfs_emubd_destroy(&cfg);
|
err = lfs3_emubd_destroy(&cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1359,19 +1359,19 @@ static void run_powerloss_linear(
|
|||||||
TEST_PLS = 0;
|
TEST_PLS = 0;
|
||||||
|
|
||||||
// create block device and configuration
|
// create block device and configuration
|
||||||
lfs_emubd_t bd;
|
lfs3_emubd_t bd;
|
||||||
jmp_buf powerloss_jmp;
|
jmp_buf powerloss_jmp;
|
||||||
|
|
||||||
struct lfs_config cfg = {
|
struct lfs3_config cfg = {
|
||||||
.context = &bd,
|
.context = &bd,
|
||||||
.read = lfs_emubd_read,
|
.read = lfs3_emubd_read,
|
||||||
.prog = lfs_emubd_prog,
|
.prog = lfs3_emubd_prog,
|
||||||
.erase = lfs_emubd_erase,
|
.erase = lfs3_emubd_erase,
|
||||||
.sync = lfs_emubd_sync,
|
.sync = lfs3_emubd_sync,
|
||||||
TEST_CFG
|
TEST_CFG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_emubd_config bdcfg = {
|
struct lfs3_emubd_config bdcfg = {
|
||||||
.disk_path = test_disk_path,
|
.disk_path = test_disk_path,
|
||||||
.read_sleep = test_read_sleep,
|
.read_sleep = test_read_sleep,
|
||||||
.prog_sleep = test_prog_sleep,
|
.prog_sleep = test_prog_sleep,
|
||||||
@@ -1384,7 +1384,7 @@ static void run_powerloss_linear(
|
|||||||
TEST_BDCFG
|
TEST_BDCFG
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not create block device: %d\n", err);
|
fprintf(stderr, "error: could not create block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1411,7 +1411,7 @@ static void run_powerloss_linear(
|
|||||||
|
|
||||||
// increment pls
|
// increment pls
|
||||||
TEST_PLS += 1;
|
TEST_PLS += 1;
|
||||||
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
|
lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
|
||||||
? TEST_PLS+1
|
? TEST_PLS+1
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
@@ -1421,7 +1421,7 @@ static void run_powerloss_linear(
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
err = lfs_emubd_destroy(&cfg);
|
err = lfs3_emubd_destroy(&cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1436,19 +1436,19 @@ static void run_powerloss_log(
|
|||||||
TEST_PLS = 0;
|
TEST_PLS = 0;
|
||||||
|
|
||||||
// create block device and configuration
|
// create block device and configuration
|
||||||
lfs_emubd_t bd;
|
lfs3_emubd_t bd;
|
||||||
jmp_buf powerloss_jmp;
|
jmp_buf powerloss_jmp;
|
||||||
|
|
||||||
struct lfs_config cfg = {
|
struct lfs3_config cfg = {
|
||||||
.context = &bd,
|
.context = &bd,
|
||||||
.read = lfs_emubd_read,
|
.read = lfs3_emubd_read,
|
||||||
.prog = lfs_emubd_prog,
|
.prog = lfs3_emubd_prog,
|
||||||
.erase = lfs_emubd_erase,
|
.erase = lfs3_emubd_erase,
|
||||||
.sync = lfs_emubd_sync,
|
.sync = lfs3_emubd_sync,
|
||||||
TEST_CFG
|
TEST_CFG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_emubd_config bdcfg = {
|
struct lfs3_emubd_config bdcfg = {
|
||||||
.disk_path = test_disk_path,
|
.disk_path = test_disk_path,
|
||||||
.read_sleep = test_read_sleep,
|
.read_sleep = test_read_sleep,
|
||||||
.prog_sleep = test_prog_sleep,
|
.prog_sleep = test_prog_sleep,
|
||||||
@@ -1461,7 +1461,7 @@ static void run_powerloss_log(
|
|||||||
TEST_BDCFG
|
TEST_BDCFG
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not create block device: %d\n", err);
|
fprintf(stderr, "error: could not create block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1488,7 +1488,7 @@ static void run_powerloss_log(
|
|||||||
|
|
||||||
// increment pls
|
// increment pls
|
||||||
TEST_PLS += 1;
|
TEST_PLS += 1;
|
||||||
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
|
lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
|
||||||
? 1 << TEST_PLS
|
? 1 << TEST_PLS
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
@@ -1498,7 +1498,7 @@ static void run_powerloss_log(
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
err = lfs_emubd_destroy(&cfg);
|
err = lfs3_emubd_destroy(&cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1513,19 +1513,19 @@ static void run_powerloss_cycles(
|
|||||||
TEST_PLS = 0;
|
TEST_PLS = 0;
|
||||||
|
|
||||||
// create block device and configuration
|
// create block device and configuration
|
||||||
lfs_emubd_t bd;
|
lfs3_emubd_t bd;
|
||||||
jmp_buf powerloss_jmp;
|
jmp_buf powerloss_jmp;
|
||||||
|
|
||||||
struct lfs_config cfg = {
|
struct lfs3_config cfg = {
|
||||||
.context = &bd,
|
.context = &bd,
|
||||||
.read = lfs_emubd_read,
|
.read = lfs3_emubd_read,
|
||||||
.prog = lfs_emubd_prog,
|
.prog = lfs3_emubd_prog,
|
||||||
.erase = lfs_emubd_erase,
|
.erase = lfs3_emubd_erase,
|
||||||
.sync = lfs_emubd_sync,
|
.sync = lfs3_emubd_sync,
|
||||||
TEST_CFG
|
TEST_CFG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_emubd_config bdcfg = {
|
struct lfs3_emubd_config bdcfg = {
|
||||||
.disk_path = test_disk_path,
|
.disk_path = test_disk_path,
|
||||||
.read_sleep = test_read_sleep,
|
.read_sleep = test_read_sleep,
|
||||||
.prog_sleep = test_prog_sleep,
|
.prog_sleep = test_prog_sleep,
|
||||||
@@ -1538,7 +1538,7 @@ static void run_powerloss_cycles(
|
|||||||
TEST_BDCFG
|
TEST_BDCFG
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not create block device: %d\n", err);
|
fprintf(stderr, "error: could not create block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1564,7 +1564,7 @@ static void run_powerloss_cycles(
|
|||||||
|
|
||||||
// increment pls
|
// increment pls
|
||||||
TEST_PLS += 1;
|
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]
|
? powerloss->cycles[TEST_PLS]
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
@@ -1574,7 +1574,7 @@ static void run_powerloss_cycles(
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
err = lfs_emubd_destroy(&cfg);
|
err = lfs3_emubd_destroy(&cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1582,15 +1582,15 @@ static void run_powerloss_cycles(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct powerloss_exhaustive_state {
|
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_count;
|
||||||
size_t branch_capacity;
|
size_t branch_capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct powerloss_exhaustive_cycles {
|
struct powerloss_exhaustive_cycles {
|
||||||
lfs_emubd_powercycles_t *cycles;
|
lfs3_emubd_powercycles_t *cycles;
|
||||||
size_t cycle_count;
|
size_t cycle_count;
|
||||||
size_t cycle_capacity;
|
size_t cycle_capacity;
|
||||||
};
|
};
|
||||||
@@ -1598,9 +1598,9 @@ struct powerloss_exhaustive_cycles {
|
|||||||
static void powerloss_exhaustive_branch(void *c) {
|
static void powerloss_exhaustive_branch(void *c) {
|
||||||
struct powerloss_exhaustive_state *state = c;
|
struct powerloss_exhaustive_state *state = c;
|
||||||
// append to branches
|
// append to branches
|
||||||
lfs_emubd_t *branch = mappend(
|
lfs3_emubd_t *branch = mappend(
|
||||||
(void**)&state->branches,
|
(void**)&state->branches,
|
||||||
sizeof(lfs_emubd_t),
|
sizeof(lfs3_emubd_t),
|
||||||
&state->branch_count,
|
&state->branch_count,
|
||||||
&state->branch_capacity);
|
&state->branch_capacity);
|
||||||
if (!branch) {
|
if (!branch) {
|
||||||
@@ -1609,22 +1609,22 @@ static void powerloss_exhaustive_branch(void *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create copy-on-write copy
|
// create copy-on-write copy
|
||||||
int err = lfs_emubd_cpy(state->cfg, branch);
|
int err = lfs3_emubd_cpy(state->cfg, branch);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: exhaustive: could not create bd copy\n");
|
fprintf(stderr, "error: exhaustive: could not create bd copy\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// also trigger on next power cycle
|
// also trigger on next power cycle
|
||||||
lfs_emubd_setpowercycles(state->cfg, 1);
|
lfs3_emubd_setpowercycles(state->cfg, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run_powerloss_exhaustive_layer(
|
static void run_powerloss_exhaustive_layer(
|
||||||
struct powerloss_exhaustive_cycles *cycles,
|
struct powerloss_exhaustive_cycles *cycles,
|
||||||
const struct test_suite *suite,
|
const struct test_suite *suite,
|
||||||
const struct test_case *case_,
|
const struct test_case *case_,
|
||||||
struct lfs_config *cfg,
|
struct lfs3_config *cfg,
|
||||||
struct lfs_emubd_config *bdcfg,
|
struct lfs3_emubd_config *bdcfg,
|
||||||
size_t depth,
|
size_t depth,
|
||||||
size_t pls) {
|
size_t pls) {
|
||||||
struct powerloss_exhaustive_state state = {
|
struct powerloss_exhaustive_state state = {
|
||||||
@@ -1639,14 +1639,14 @@ static void run_powerloss_exhaustive_layer(
|
|||||||
|
|
||||||
// run through the test without additional powerlosses, collecting possible
|
// run through the test without additional powerlosses, collecting possible
|
||||||
// branches as we do so
|
// 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;
|
bdcfg->powerloss_data = &state;
|
||||||
|
|
||||||
// run the tests
|
// run the tests
|
||||||
case_->run(cfg);
|
case_->run(cfg);
|
||||||
|
|
||||||
// aggressively clean up memory here to try to keep our memory usage low
|
// 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) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
fprintf(stderr, "error: could not destroy block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -1655,9 +1655,9 @@ static void run_powerloss_exhaustive_layer(
|
|||||||
// recurse into each branch
|
// recurse into each branch
|
||||||
for (size_t i = 0; i < state.branch_count; i++) {
|
for (size_t i = 0; i < state.branch_count; i++) {
|
||||||
// first push and print the branch
|
// first push and print the branch
|
||||||
lfs_emubd_powercycles_t *cycle = mappend(
|
lfs3_emubd_powercycles_t *cycle = mappend(
|
||||||
(void**)&cycles->cycles,
|
(void**)&cycles->cycles,
|
||||||
sizeof(lfs_emubd_powercycles_t),
|
sizeof(lfs3_emubd_powercycles_t),
|
||||||
&cycles->cycle_count,
|
&cycles->cycle_count,
|
||||||
&cycles->cycle_capacity);
|
&cycles->cycle_capacity);
|
||||||
if (!cycle) {
|
if (!cycle) {
|
||||||
@@ -1689,18 +1689,18 @@ static void run_powerloss_exhaustive(
|
|||||||
const struct test_suite *suite,
|
const struct test_suite *suite,
|
||||||
const struct test_case *case_) {
|
const struct test_case *case_) {
|
||||||
// create block device and configuration
|
// create block device and configuration
|
||||||
lfs_emubd_t bd;
|
lfs3_emubd_t bd;
|
||||||
|
|
||||||
struct lfs_config cfg = {
|
struct lfs3_config cfg = {
|
||||||
.context = &bd,
|
.context = &bd,
|
||||||
.read = lfs_emubd_read,
|
.read = lfs3_emubd_read,
|
||||||
.prog = lfs_emubd_prog,
|
.prog = lfs3_emubd_prog,
|
||||||
.erase = lfs_emubd_erase,
|
.erase = lfs3_emubd_erase,
|
||||||
.sync = lfs_emubd_sync,
|
.sync = lfs3_emubd_sync,
|
||||||
TEST_CFG
|
TEST_CFG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_emubd_config bdcfg = {
|
struct lfs3_emubd_config bdcfg = {
|
||||||
.disk_path = test_disk_path,
|
.disk_path = test_disk_path,
|
||||||
.read_sleep = test_read_sleep,
|
.read_sleep = test_read_sleep,
|
||||||
.prog_sleep = test_prog_sleep,
|
.prog_sleep = test_prog_sleep,
|
||||||
@@ -1710,7 +1710,7 @@ static void run_powerloss_exhaustive(
|
|||||||
TEST_BDCFG
|
TEST_BDCFG
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "error: could not create block device: %d\n", err);
|
fprintf(stderr, "error: could not create block device: %d\n", err);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@@ -2234,16 +2234,16 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// comma-separated permutation
|
// comma-separated permutation
|
||||||
if (*optarg == '{') {
|
if (*optarg == '{') {
|
||||||
lfs_emubd_powercycles_t *cycles = NULL;
|
lfs3_emubd_powercycles_t *cycles = NULL;
|
||||||
size_t cycle_count = 0;
|
size_t cycle_count = 0;
|
||||||
size_t cycle_capacity = 0;
|
size_t cycle_capacity = 0;
|
||||||
|
|
||||||
char *s = optarg + 1;
|
char *s = optarg + 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
parsed = NULL;
|
parsed = NULL;
|
||||||
*(lfs_emubd_powercycles_t*)mappend(
|
*(lfs3_emubd_powercycles_t*)mappend(
|
||||||
(void**)&cycles,
|
(void**)&cycles,
|
||||||
sizeof(lfs_emubd_powercycles_t),
|
sizeof(lfs3_emubd_powercycles_t),
|
||||||
&cycle_count,
|
&cycle_count,
|
||||||
&cycle_capacity)
|
&cycle_capacity)
|
||||||
= strtoumax(s, &parsed, 0);
|
= strtoumax(s, &parsed, 0);
|
||||||
@@ -2295,7 +2295,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// otherwise explicit power cycles
|
// otherwise explicit power cycles
|
||||||
} else {
|
} else {
|
||||||
lfs_emubd_powercycles_t *cycles = NULL;
|
lfs3_emubd_powercycles_t *cycles = NULL;
|
||||||
size_t cycle_count = 0;
|
size_t cycle_count = 0;
|
||||||
size_t cycle_capacity = 0;
|
size_t cycle_capacity = 0;
|
||||||
|
|
||||||
@@ -2307,9 +2307,9 @@ int main(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(lfs_emubd_powercycles_t*)mappend(
|
*(lfs3_emubd_powercycles_t*)mappend(
|
||||||
(void**)&cycles,
|
(void**)&cycles,
|
||||||
sizeof(lfs_emubd_powercycles_t),
|
sizeof(lfs3_emubd_powercycles_t),
|
||||||
&cycle_count,
|
&cycle_count,
|
||||||
&cycle_capacity) = x;
|
&cycle_capacity) = x;
|
||||||
s = parsed;
|
s = parsed;
|
||||||
@@ -2538,7 +2538,7 @@ getopt_done:;
|
|||||||
|
|
||||||
if (d >= define_count) {
|
if (d >= define_count) {
|
||||||
// align to power of two to avoid any superlinear growth
|
// 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,
|
defines = realloc(defines,
|
||||||
ncount*sizeof(test_define_t));
|
ncount*sizeof(test_define_t));
|
||||||
memset(defines+define_count, 0,
|
memset(defines+define_count, 0,
|
||||||
@@ -2588,14 +2588,14 @@ getopt_done:;
|
|||||||
// otherwise explicit power cycles
|
// otherwise explicit power cycles
|
||||||
} else if (cycles_) {
|
} else if (cycles_) {
|
||||||
// parse power cycles
|
// parse power cycles
|
||||||
lfs_emubd_powercycles_t *cycles = NULL;
|
lfs3_emubd_powercycles_t *cycles = NULL;
|
||||||
size_t cycle_count = 0;
|
size_t cycle_count = 0;
|
||||||
size_t cycle_capacity = 0;
|
size_t cycle_capacity = 0;
|
||||||
while (*cycles_ != '\0') {
|
while (*cycles_ != '\0') {
|
||||||
char *parsed = NULL;
|
char *parsed = NULL;
|
||||||
*(lfs_emubd_powercycles_t*)mappend(
|
*(lfs3_emubd_powercycles_t*)mappend(
|
||||||
(void**)&cycles,
|
(void**)&cycles,
|
||||||
sizeof(lfs_emubd_powercycles_t),
|
sizeof(lfs3_emubd_powercycles_t),
|
||||||
&cycle_count,
|
&cycle_count,
|
||||||
&cycle_capacity)
|
&cycle_capacity)
|
||||||
= leb16_parse(cycles_, &parsed);
|
= leb16_parse(cycles_, &parsed);
|
||||||
|
|||||||
+13
-13
@@ -8,20 +8,20 @@
|
|||||||
#define TEST_RUNNER_H
|
#define TEST_RUNNER_H
|
||||||
|
|
||||||
|
|
||||||
// override LFS_TRACE
|
// override LFS3_TRACE
|
||||||
void test_trace(const char *fmt, ...);
|
void test_trace(const char *fmt, ...);
|
||||||
|
|
||||||
#define LFS_TRACE_(fmt, ...) \
|
#define LFS3_TRACE_(fmt, ...) \
|
||||||
test_trace("%s:%d:trace: " fmt "%s\n", \
|
test_trace("%s:%d:trace: " fmt "%s\n", \
|
||||||
__FILE__, \
|
__FILE__, \
|
||||||
__LINE__, \
|
__LINE__, \
|
||||||
__VA_ARGS__)
|
__VA_ARGS__)
|
||||||
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
#define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
|
||||||
#define LFS_EMUBD_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
#define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
|
||||||
|
|
||||||
|
|
||||||
// note these are indirectly included in any generated files
|
// note these are indirectly included in any generated files
|
||||||
#include "bd/lfs_emubd.h"
|
#include "bd/lfs3_emubd.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// give source a chance to define feature macros
|
// give source a chance to define feature macros
|
||||||
@@ -30,7 +30,7 @@ void test_trace(const char *fmt, ...);
|
|||||||
|
|
||||||
|
|
||||||
// generated test configurations
|
// generated test configurations
|
||||||
struct lfs_config;
|
struct lfs3_config;
|
||||||
|
|
||||||
enum test_flags {
|
enum test_flags {
|
||||||
TEST_INTERNAL = 0x1,
|
TEST_INTERNAL = 0x1,
|
||||||
@@ -56,7 +56,7 @@ struct test_case {
|
|||||||
size_t permutations;
|
size_t permutations;
|
||||||
|
|
||||||
bool (*if_)(void);
|
bool (*if_)(void);
|
||||||
void (*run)(struct lfs_config *cfg);
|
void (*run)(struct lfs3_config *cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct test_suite {
|
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(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \
|
||||||
TEST_DEFINE(DISK_SIZE, 1024*1024 ) \
|
TEST_DEFINE(DISK_SIZE, 1024*1024 ) \
|
||||||
TEST_DEFINE(BLOCK_RECYCLES, -1 ) \
|
TEST_DEFINE(BLOCK_RECYCLES, -1 ) \
|
||||||
TEST_DEFINE(RCACHE_SIZE, LFS_MAX(16, READ_SIZE) ) \
|
TEST_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) ) \
|
||||||
TEST_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \
|
TEST_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \
|
||||||
TEST_DEFINE(FILE_CACHE_SIZE, 16 ) \
|
TEST_DEFINE(FILE_CACHE_SIZE, 16 ) \
|
||||||
TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \
|
||||||
TEST_DEFINE(GC_FLAGS, 0 ) \
|
TEST_DEFINE(GC_FLAGS, 0 ) \
|
||||||
TEST_DEFINE(GC_STEPS, 0 ) \
|
TEST_DEFINE(GC_STEPS, 0 ) \
|
||||||
TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \
|
||||||
TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
|
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(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
|
||||||
TEST_DEFINE(FRAGMENT_THRESH, -1 ) \
|
TEST_DEFINE(FRAGMENT_THRESH, -1 ) \
|
||||||
TEST_DEFINE(ERASE_VALUE, 0xff ) \
|
TEST_DEFINE(ERASE_VALUE, 0xff ) \
|
||||||
TEST_DEFINE(ERASE_CYCLES, 0 ) \
|
TEST_DEFINE(ERASE_CYCLES, 0 ) \
|
||||||
TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS_EMUBD_BADBLOCK_PROGERROR ) \
|
TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
|
||||||
TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS_EMUBD_POWERLOSS_ATOMIC ) \
|
TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) \
|
||||||
TEST_DEFINE(EMUBD_SEED, 0 )
|
TEST_DEFINE(EMUBD_SEED, 0 )
|
||||||
|
|
||||||
// declare defines as global intmax_ts
|
// 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, \
|
.crystal_thresh = CRYSTAL_THRESH, \
|
||||||
.fragment_thresh = FRAGMENT_THRESH,
|
.fragment_thresh = FRAGMENT_THRESH,
|
||||||
|
|
||||||
#ifdef LFS_GC
|
#ifdef LFS3_GC
|
||||||
#define TEST_GC_CFG \
|
#define TEST_GC_CFG \
|
||||||
.gc_flags = GC_FLAGS, \
|
.gc_flags = GC_FLAGS, \
|
||||||
.gc_steps = GC_STEPS,
|
.gc_steps = GC_STEPS,
|
||||||
|
|||||||
+2
-2
@@ -432,7 +432,7 @@ def compile(bench_paths, **args):
|
|||||||
# create case run function
|
# create case run function
|
||||||
f.writeln('void __bench__%s__run('
|
f.writeln('void __bench__%s__run('
|
||||||
'__attribute__((unused)) '
|
'__attribute__((unused)) '
|
||||||
'struct lfs_config *CFG) {' % (
|
'struct lfs3_config *CFG) {' % (
|
||||||
case.name))
|
case.name))
|
||||||
f.writeln(4*' '+'// bench case %s' % case.name)
|
f.writeln(4*' '+'// bench case %s' % case.name)
|
||||||
if case.code_lineno is not None:
|
if case.code_lineno is not None:
|
||||||
@@ -491,7 +491,7 @@ def compile(bench_paths, **args):
|
|||||||
'void);' % (
|
'void);' % (
|
||||||
case.name))
|
case.name))
|
||||||
f.writeln('extern void __bench__%s__run('
|
f.writeln('extern void __bench__%s__run('
|
||||||
'struct lfs_config *CFG);' % (
|
'struct lfs3_config *CFG);' % (
|
||||||
case.name))
|
case.name))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -2769,7 +2769,7 @@ class Gstate:
|
|||||||
|
|
||||||
|
|
||||||
# high-level littlefs representation
|
# high-level littlefs representation
|
||||||
class Lfs:
|
class Lfs3:
|
||||||
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
||||||
corrupt=False):
|
corrupt=False):
|
||||||
self.bd = bd
|
self.bd = bd
|
||||||
@@ -3018,7 +3018,7 @@ class Lfs:
|
|||||||
|
|
||||||
# empty path?
|
# empty path?
|
||||||
if path_ == b'':
|
if path_ == b'':
|
||||||
raise Lfs.PathError("invalid path: %r" % path)
|
raise Lfs3.PathError("invalid path: %r" % path)
|
||||||
|
|
||||||
path__ = []
|
path__ = []
|
||||||
for p in path_.split(b'/'):
|
for p in path_.split(b'/'):
|
||||||
@@ -3039,7 +3039,7 @@ class Lfs:
|
|||||||
else:
|
else:
|
||||||
path__.append(p)
|
path__.append(p)
|
||||||
if dotdots:
|
if dotdots:
|
||||||
raise Lfs.PathError("invalid path: %r" % path)
|
raise Lfs3.PathError("invalid path: %r" % path)
|
||||||
path__.reverse()
|
path__.reverse()
|
||||||
path_ = path__
|
path_ = path__
|
||||||
|
|
||||||
@@ -3570,7 +3570,7 @@ class Lfs:
|
|||||||
super().__init__(lfs, mid, mdir, tag, name)
|
super().__init__(lfs, mid, mdir, tag, name)
|
||||||
|
|
||||||
# we're recursable if we're a non-grmed directory with a did
|
# 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 not self.grmed
|
||||||
and self.did is not None):
|
and self.did is not None):
|
||||||
self.recursable = True
|
self.recursable = True
|
||||||
@@ -4507,7 +4507,7 @@ def main_(ring, disk, mroots=None, *,
|
|||||||
|
|
||||||
# fetch the filesystem
|
# fetch the filesystem
|
||||||
bd = Bd(f, block_size, block_count)
|
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
|
# don't bother to check things if we're not reporting errors
|
||||||
no_ck=not args.get('error_on_corrupt'))
|
no_ck=not args.get('error_on_corrupt'))
|
||||||
corrupted = not bool(lfs)
|
corrupted = not bool(lfs)
|
||||||
|
|||||||
@@ -2799,7 +2799,7 @@ class Gstate:
|
|||||||
|
|
||||||
|
|
||||||
# high-level littlefs representation
|
# high-level littlefs representation
|
||||||
class Lfs:
|
class Lfs3:
|
||||||
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
||||||
corrupt=False):
|
corrupt=False):
|
||||||
self.bd = bd
|
self.bd = bd
|
||||||
@@ -3048,7 +3048,7 @@ class Lfs:
|
|||||||
|
|
||||||
# empty path?
|
# empty path?
|
||||||
if path_ == b'':
|
if path_ == b'':
|
||||||
raise Lfs.PathError("invalid path: %r" % path)
|
raise Lfs3.PathError("invalid path: %r" % path)
|
||||||
|
|
||||||
path__ = []
|
path__ = []
|
||||||
for p in path_.split(b'/'):
|
for p in path_.split(b'/'):
|
||||||
@@ -3069,7 +3069,7 @@ class Lfs:
|
|||||||
else:
|
else:
|
||||||
path__.append(p)
|
path__.append(p)
|
||||||
if dotdots:
|
if dotdots:
|
||||||
raise Lfs.PathError("invalid path: %r" % path)
|
raise Lfs3.PathError("invalid path: %r" % path)
|
||||||
path__.reverse()
|
path__.reverse()
|
||||||
path_ = path__
|
path_ = path__
|
||||||
|
|
||||||
@@ -3600,7 +3600,7 @@ class Lfs:
|
|||||||
super().__init__(lfs, mid, mdir, tag, name)
|
super().__init__(lfs, mid, mdir, tag, name)
|
||||||
|
|
||||||
# we're recursable if we're a non-grmed directory with a did
|
# 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 not self.grmed
|
||||||
and self.did is not None):
|
and self.did is not None):
|
||||||
self.recursable = True
|
self.recursable = True
|
||||||
@@ -4227,7 +4227,7 @@ def main(disk, output, mroots=None, *,
|
|||||||
|
|
||||||
# fetch the filesystem
|
# fetch the filesystem
|
||||||
bd = Bd(f, block_size, block_count)
|
bd = Bd(f, block_size, block_count)
|
||||||
lfs = Lfs.fetch(bd, mroots, trunk)
|
lfs = Lfs3.fetch(bd, mroots, trunk)
|
||||||
corrupted = not bool(lfs)
|
corrupted = not bool(lfs)
|
||||||
|
|
||||||
# if we can't figure out the block_count, guess
|
# if we can't figure out the block_count, guess
|
||||||
|
|||||||
+4
-4
@@ -35,14 +35,14 @@ def main(errs, *,
|
|||||||
# list all known error codes
|
# list all known error codes
|
||||||
if list_:
|
if list_:
|
||||||
for n, e, h in ERRS:
|
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
|
# find these errors
|
||||||
else:
|
else:
|
||||||
def find_err(err):
|
def find_err(err):
|
||||||
# find by LFS_ERR_+name
|
# find by LFS3_ERR_+name
|
||||||
for n, e, h in ERRS:
|
for n, e, h in ERRS:
|
||||||
if 'LFS_ERR_'+n == err.upper():
|
if 'LFS3_ERR_'+n == err.upper():
|
||||||
return n, e, h
|
return n, e, h
|
||||||
# find by ERR_+name
|
# find by ERR_+name
|
||||||
for n, e, h in ERRS:
|
for n, e, h in ERRS:
|
||||||
@@ -73,7 +73,7 @@ def main(errs, *,
|
|||||||
for err in errs:
|
for err in errs:
|
||||||
try:
|
try:
|
||||||
n, e, h = find_err(err)
|
n, e, h = find_err(err)
|
||||||
lines.append(('LFS_ERR_'+n, str(e), h))
|
lines.append(('LFS3_ERR_'+n, str(e), h))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
lines.append(('?', err, 'Unknown err code'))
|
lines.append(('?', err, 'Unknown err code'))
|
||||||
|
|
||||||
|
|||||||
+22
-22
@@ -77,8 +77,8 @@ FLAGS = [
|
|||||||
('M', 'MODE', 1, "Mount's access mode" ),
|
('M', 'MODE', 1, "Mount's access mode" ),
|
||||||
('^', 'RDWR', 0, "Mount the filesystem as read and write" ),
|
('^', 'RDWR', 0, "Mount the filesystem as read and write" ),
|
||||||
('^', 'RDONLY', 1, "Mount the filesystem as read only" ),
|
('^', 'RDONLY', 1, "Mount the filesystem as read only" ),
|
||||||
('M', 'FLUSH', 0x00000040, "Open all files with LFS_O_FLUSH" ),
|
('M', 'FLUSH', 0x00000040, "Open all files with LFS3_O_FLUSH" ),
|
||||||
('M', 'SYNC', 0x00000080, "Open all files with LFS_O_SYNC" ),
|
('M', 'SYNC', 0x00000080, "Open all files with LFS3_O_SYNC" ),
|
||||||
('M', 'REVDBG', 0x00000010, "Add debug info to revision counts" ),
|
('M', 'REVDBG', 0x00000010, "Add debug info to revision counts" ),
|
||||||
('M', 'REVNOISE', 0x00000020, "Add noise to revision counts" ),
|
('M', 'REVNOISE', 0x00000020, "Add noise to revision counts" ),
|
||||||
('M', 'CKPROGS', 0x00080000, "Check progs by reading back progged data" ),
|
('M', 'CKPROGS', 0x00080000, "Check progs by reading back progged data" ),
|
||||||
@@ -105,16 +105,16 @@ FLAGS = [
|
|||||||
|
|
||||||
# Filesystem info flags
|
# Filesystem info flags
|
||||||
('I', 'RDONLY', 0x00000001, "Mounted read only" ),
|
('I', 'RDONLY', 0x00000001, "Mounted read only" ),
|
||||||
('I', 'FLUSH', 0x00000040, "Mounted with LFS_M_FLUSH" ),
|
('I', 'FLUSH', 0x00000040, "Mounted with LFS3_M_FLUSH" ),
|
||||||
('I', 'SYNC', 0x00000080, "Mounted with LFS_M_SYNC" ),
|
('I', 'SYNC', 0x00000080, "Mounted with LFS3_M_SYNC" ),
|
||||||
('I', 'REVDBG', 0x00000010, "Mounted with LFS_M_REVDBG" ),
|
('I', 'REVDBG', 0x00000010, "Mounted with LFS3_M_REVDBG" ),
|
||||||
('I', 'REVNOISE', 0x00000020, "Mounted with LFS_M_REVNOISE" ),
|
('I', 'REVNOISE', 0x00000020, "Mounted with LFS3_M_REVNOISE" ),
|
||||||
('I', 'CKPROGS', 0x00080000, "Mounted with LFS_M_CKPROGS" ),
|
('I', 'CKPROGS', 0x00080000, "Mounted with LFS3_M_CKPROGS" ),
|
||||||
('I', 'CKFETCHES', 0x00100000, "Mounted with LFS_M_CKFETCHES" ),
|
('I', 'CKFETCHES', 0x00100000, "Mounted with LFS3_M_CKFETCHES" ),
|
||||||
('I', 'CKMETAPARITY',
|
('I', 'CKMETAPARITY',
|
||||||
0x00200000, "Mounted with LFS_M_CKMETAPARITY" ),
|
0x00200000, "Mounted with LFS3_M_CKMETAPARITY" ),
|
||||||
('I', 'CKDATACKSUMREADS',
|
('I', 'CKDATACKSUMREADS',
|
||||||
0x00800000, "Mounted with LFS_M_CKDATACKSUMREADS" ),
|
0x00800000, "Mounted with LFS3_M_CKDATACKSUMREADS" ),
|
||||||
|
|
||||||
('I', 'MKCONSISTENT',
|
('I', 'MKCONSISTENT',
|
||||||
0x00000100, "Filesystem needs mkconsistent to write" ),
|
0x00000100, "Filesystem needs mkconsistent to write" ),
|
||||||
@@ -233,10 +233,10 @@ def main(flags, *,
|
|||||||
# accept prefix prefix
|
# accept prefix prefix
|
||||||
if f.upper() in prefixes:
|
if f.upper() in prefixes:
|
||||||
prefix.update(prefixes[f.upper()])
|
prefix.update(prefixes[f.upper()])
|
||||||
# accept LFS_+prefix prefix
|
# accept LFS3_+prefix prefix
|
||||||
elif (f.upper().startswith('LFS_')
|
elif (f.upper().startswith('LFS3_')
|
||||||
and f.upper()[len('LFS_'):] in prefixes):
|
and f.upper()[len('LFS3_'):] in prefixes):
|
||||||
prefix.update(prefixes[f.upper()[len('LFS_'):]])
|
prefix.update(prefixes[f.upper()[len('LFS3_'):]])
|
||||||
else:
|
else:
|
||||||
flags_.append(f)
|
flags_.append(f)
|
||||||
|
|
||||||
@@ -261,30 +261,30 @@ def main(flags, *,
|
|||||||
for p, t, n, f, h in flags__:
|
for p, t, n, f, h in flags__:
|
||||||
if not all_ and (t is not None or p[0].islower()):
|
if not all_ and (t is not None or p[0].islower()):
|
||||||
continue
|
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
|
# find flags by name or value
|
||||||
else:
|
else:
|
||||||
for f_ in flags_:
|
for f_ in flags_:
|
||||||
found = False
|
found = False
|
||||||
# find by LFS_+prefix+_+name
|
# find by LFS3_+prefix+_+name
|
||||||
for p, t, n, f, h in flags__:
|
for p, t, n, f, h in flags__:
|
||||||
if 'LFS_%s_%s' % (p, n) == f_.upper():
|
if 'LFS3_%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
|
found = True
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
# find by prefix+_+name
|
# find by prefix+_+name
|
||||||
for p, t, n, f, h in flags__:
|
for p, t, n, f, h in flags__:
|
||||||
if '%s_%s' % (p, n) == f_.upper():
|
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
|
found = True
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
# find by name
|
# find by name
|
||||||
for p, t, n, f, h in flags__:
|
for p, t, n, f, h in flags__:
|
||||||
if n == f_.upper():
|
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
|
found = True
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
@@ -298,11 +298,11 @@ def main(flags, *,
|
|||||||
continue
|
continue
|
||||||
# matches flag?
|
# matches flag?
|
||||||
if t is None and (f__ & f) == f:
|
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
|
f___ &= ~f
|
||||||
# matches type?
|
# matches type?
|
||||||
elif t is not None and (f__ & t) == f:
|
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
|
f___ &= ~t
|
||||||
if f___:
|
if f___:
|
||||||
lines.append(('?', '0x%08x' % f___, 'Unknown flags'))
|
lines.append(('?', '0x%08x' % f___, 'Unknown flags'))
|
||||||
|
|||||||
@@ -2726,7 +2726,7 @@ class Gstate:
|
|||||||
|
|
||||||
|
|
||||||
# high-level littlefs representation
|
# high-level littlefs representation
|
||||||
class Lfs:
|
class Lfs3:
|
||||||
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
|
||||||
corrupt=False):
|
corrupt=False):
|
||||||
self.bd = bd
|
self.bd = bd
|
||||||
@@ -2975,7 +2975,7 @@ class Lfs:
|
|||||||
|
|
||||||
# empty path?
|
# empty path?
|
||||||
if path_ == b'':
|
if path_ == b'':
|
||||||
raise Lfs.PathError("invalid path: %r" % path)
|
raise Lfs3.PathError("invalid path: %r" % path)
|
||||||
|
|
||||||
path__ = []
|
path__ = []
|
||||||
for p in path_.split(b'/'):
|
for p in path_.split(b'/'):
|
||||||
@@ -2996,7 +2996,7 @@ class Lfs:
|
|||||||
else:
|
else:
|
||||||
path__.append(p)
|
path__.append(p)
|
||||||
if dotdots:
|
if dotdots:
|
||||||
raise Lfs.PathError("invalid path: %r" % path)
|
raise Lfs3.PathError("invalid path: %r" % path)
|
||||||
path__.reverse()
|
path__.reverse()
|
||||||
path_ = path__
|
path_ = path__
|
||||||
|
|
||||||
@@ -3527,7 +3527,7 @@ class Lfs:
|
|||||||
super().__init__(lfs, mid, mdir, tag, name)
|
super().__init__(lfs, mid, mdir, tag, name)
|
||||||
|
|
||||||
# we're recursable if we're a non-grmed directory with a did
|
# 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 not self.grmed
|
||||||
and self.did is not None):
|
and self.did is not None):
|
||||||
self.recursable = True
|
self.recursable = True
|
||||||
@@ -4157,7 +4157,7 @@ def dbg_files(lfs, paths, *,
|
|||||||
try:
|
try:
|
||||||
dir = lfs.pathlookup(path,
|
dir = lfs.pathlookup(path,
|
||||||
all=args.get('all'))
|
all=args.get('all'))
|
||||||
except Lfs.PathError as e:
|
except Lfs3.PathError as e:
|
||||||
print("error: %s" % e,
|
print("error: %s" % e,
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
@@ -4178,7 +4178,7 @@ def dbg_files(lfs, paths, *,
|
|||||||
|
|
||||||
# include any orphaned entries in the root directory to help
|
# include any orphaned entries in the root directory to help
|
||||||
# debugging (these don't actually live in the root directory)
|
# 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
|
# finding orphans is expensive, so cache this
|
||||||
if not hasattr(iter_dir, 'orphans'):
|
if not hasattr(iter_dir, 'orphans'):
|
||||||
iter_dir.orphans = dir.lfs.orphans()
|
iter_dir.orphans = dir.lfs.orphans()
|
||||||
@@ -4224,7 +4224,7 @@ def dbg_files(lfs, paths, *,
|
|||||||
if file.orphaned:
|
if file.orphaned:
|
||||||
notes.append('orphaned')
|
notes.append('orphaned')
|
||||||
# missing bookmark/did?
|
# missing bookmark/did?
|
||||||
if isinstance(file, Lfs.Dir):
|
if isinstance(file, Lfs3.Dir):
|
||||||
if file.did is None:
|
if file.did is None:
|
||||||
notes.append('missing did')
|
notes.append('missing did')
|
||||||
elif lfs.namelookup(file.did, b'') is None:
|
elif lfs.namelookup(file.did, b'') is None:
|
||||||
@@ -4582,7 +4582,7 @@ def main(disk, mroots=None, paths=None, *,
|
|||||||
|
|
||||||
# fetch the filesystem
|
# fetch the filesystem
|
||||||
bd = Bd(f, block_size, block_count)
|
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
|
# print some information about the filesystem
|
||||||
if not quiet:
|
if not quiet:
|
||||||
+2
-2
@@ -444,7 +444,7 @@ def compile(test_paths, **args):
|
|||||||
# create case run function
|
# create case run function
|
||||||
f.writeln('void __test__%s__run('
|
f.writeln('void __test__%s__run('
|
||||||
'__attribute__((unused)) '
|
'__attribute__((unused)) '
|
||||||
'struct lfs_config *CFG) {' % (
|
'struct lfs3_config *CFG) {' % (
|
||||||
case.name))
|
case.name))
|
||||||
f.writeln(4*' '+'// test case %s' % case.name)
|
f.writeln(4*' '+'// test case %s' % case.name)
|
||||||
if case.code_lineno is not None:
|
if case.code_lineno is not None:
|
||||||
@@ -503,7 +503,7 @@ def compile(test_paths, **args):
|
|||||||
'void);' % (
|
'void);' % (
|
||||||
case.name))
|
case.name))
|
||||||
f.writeln('extern void __test__%s__run('
|
f.writeln('extern void __test__%s__run('
|
||||||
'struct lfs_config *CFG);' % (
|
'struct lfs3_config *CFG);' % (
|
||||||
case.name))
|
case.name))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
|
|||||||
+240
-240
@@ -20,23 +20,23 @@ defines.COUNT = [
|
|||||||
'2',
|
'2',
|
||||||
]
|
]
|
||||||
defines.ERASE = [false, true]
|
defines.ERASE = [false, true]
|
||||||
in = 'lfs.c'
|
in = 'lfs3.c'
|
||||||
code = '''
|
code = '''
|
||||||
// test various block counts
|
// test various block counts
|
||||||
struct lfs_config cfg = *CFG;
|
struct lfs3_config cfg = *CFG;
|
||||||
cfg.block_count = COUNT;
|
cfg.block_count = COUNT;
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
|
||||||
|
|
||||||
// start allocating
|
// start allocating
|
||||||
lfs_alloc_ckpoint(&lfs);
|
lfs3_alloc_ckpoint(&lfs3);
|
||||||
lfs_size_t alloced = 0;
|
lfs3_size_t alloced = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
|
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
|
||||||
assert(block >= 0 || block == LFS_ERR_NOSPC);
|
assert(block >= 0 || block == LFS3_ERR_NOSPC);
|
||||||
|
|
||||||
if (block == LFS_ERR_NOSPC) {
|
if (block == LFS3_ERR_NOSPC) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
alloced += 1;
|
alloced += 1;
|
||||||
@@ -47,10 +47,10 @@ code = '''
|
|||||||
|
|
||||||
// excluding our mroot, we should have allocated exactly
|
// excluding our mroot, we should have allocated exactly
|
||||||
// block_count-2 blocks
|
// 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);
|
assert(alloced == COUNT-2);
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we can realloc after an ack
|
# test that we can realloc after an ack
|
||||||
@@ -64,23 +64,23 @@ defines.COUNT = [
|
|||||||
'2',
|
'2',
|
||||||
]
|
]
|
||||||
defines.ERASE = [false, true]
|
defines.ERASE = [false, true]
|
||||||
in = 'lfs.c'
|
in = 'lfs3.c'
|
||||||
code = '''
|
code = '''
|
||||||
// test various block counts
|
// test various block counts
|
||||||
struct lfs_config cfg = *CFG;
|
struct lfs3_config cfg = *CFG;
|
||||||
cfg.block_count = COUNT;
|
cfg.block_count = COUNT;
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
|
||||||
|
|
||||||
// start allocating
|
// start allocating
|
||||||
lfs_alloc_ckpoint(&lfs);
|
lfs3_alloc_ckpoint(&lfs3);
|
||||||
lfs_size_t alloced = 0;
|
lfs3_size_t alloced = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
|
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
|
||||||
assert(block >= 0 || block == LFS_ERR_NOSPC);
|
assert(block >= 0 || block == LFS3_ERR_NOSPC);
|
||||||
|
|
||||||
if (block == LFS_ERR_NOSPC) {
|
if (block == LFS3_ERR_NOSPC) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
alloced += 1;
|
alloced += 1;
|
||||||
@@ -91,17 +91,17 @@ code = '''
|
|||||||
|
|
||||||
// excluding our mroot, we should have allocated exactly
|
// excluding our mroot, we should have allocated exactly
|
||||||
// block_count-2 blocks
|
// 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);
|
assert(alloced == COUNT-2);
|
||||||
|
|
||||||
// ack again, effectively releasing all the previously alloced blocks
|
// ack again, effectively releasing all the previously alloced blocks
|
||||||
lfs_alloc_ckpoint(&lfs);
|
lfs3_alloc_ckpoint(&lfs3);
|
||||||
alloced = 0;
|
alloced = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
|
lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
|
||||||
assert(block >= 0 || block == LFS_ERR_NOSPC);
|
assert(block >= 0 || block == LFS3_ERR_NOSPC);
|
||||||
|
|
||||||
if (block == LFS_ERR_NOSPC) {
|
if (block == LFS3_ERR_NOSPC) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
alloced += 1;
|
alloced += 1;
|
||||||
@@ -112,10 +112,10 @@ code = '''
|
|||||||
|
|
||||||
// excluding our mroot, we should have allocated exactly
|
// excluding our mroot, we should have allocated exactly
|
||||||
// block_count-2 blocks
|
// 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);
|
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.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
||||||
defines.CKMETA = [false, true]
|
defines.CKMETA = [false, true]
|
||||||
defines.REMOUNT = [false, true]
|
defines.REMOUNT = [false, true]
|
||||||
in = 'lfs.c'
|
in = 'lfs3.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
|
|
||||||
// create this many directories
|
// 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];
|
char name[256];
|
||||||
sprintf(name, "dir%03x", i);
|
sprintf(name, "dir%03x", i);
|
||||||
lfsr_mkdir(&lfs, name) => 0;
|
lfs3_mkdir(&lfs3, name) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that our mkdir worked
|
// 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];
|
char name[256];
|
||||||
sprintf(name, "dir%03x", i);
|
sprintf(name, "dir%03x", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_dir_t dir;
|
lfs3_dir_t dir;
|
||||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
lfs3_dir_open(&lfs3, &dir, "/") => 0;
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
lfs3_dir_read(&lfs3, &dir, &info) => 0;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
lfs3_dir_read(&lfs3, &dir, &info) => 0;
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
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];
|
char name[256];
|
||||||
sprintf(name, "dir%03x", i);
|
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(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
}
|
}
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
|
||||||
lfsr_dir_close(&lfs, &dir) => 0;
|
lfs3_dir_close(&lfs3, &dir) => 0;
|
||||||
|
|
||||||
// remount?
|
// remount?
|
||||||
if (REMOUNT) {
|
if (REMOUNT) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first traverse the tree to find all blocks in use
|
// first traverse the tree to find all blocks in use
|
||||||
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
|
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
|
||||||
memset(seen, 0, (BLOCK_COUNT+7)/8);
|
memset(seen, 0, (BLOCK_COUNT+7)/8);
|
||||||
|
|
||||||
lfsr_traversal_t t;
|
lfs3_traversal_t t;
|
||||||
lfsr_traversal_init(&t,
|
lfs3_traversal_init(&t,
|
||||||
LFS_T_RDONLY
|
LFS3_T_RDONLY
|
||||||
| ((CKMETA) ? LFS_T_CKMETA : 0));
|
| ((CKMETA) ? LFS3_T_CKMETA : 0));
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs3_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
assert(i < 2*BLOCK_COUNT);
|
assert(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
lfsr_tag_t tag;
|
lfs3_tag_t tag;
|
||||||
lfsr_bptr_t bptr;
|
lfs3_bptr_t bptr;
|
||||||
int err = lfsr_mtree_traverse(&lfs, &t,
|
int err = lfs3_mtree_traverse(&lfs3, &t,
|
||||||
&tag, &bptr);
|
&tag, &bptr);
|
||||||
assert(!err || err == LFS_ERR_NOENT);
|
assert(!err || err == LFS3_ERR_NOENT);
|
||||||
if (err == LFS_ERR_NOENT) {
|
if (err == LFS3_ERR_NOENT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag == LFSR_TAG_MDIR) {
|
if (tag == LFS3_TAG_MDIR) {
|
||||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
|
||||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||||
tag,
|
tag,
|
||||||
mdir->rbyd.blocks[0],
|
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[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||||
|
|
||||||
} else if (tag == LFSR_TAG_BRANCH) {
|
} else if (tag == LFS3_TAG_BRANCH) {
|
||||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
|
||||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||||
tag,
|
tag,
|
||||||
rbyd->blocks[0], rbyd->trunk);
|
rbyd->blocks[0], rbyd->trunk);
|
||||||
@@ -227,7 +227,7 @@ code = '''
|
|||||||
// then clobber every other block
|
// then clobber every other block
|
||||||
uint8_t clobber_buf[BLOCK_SIZE];
|
uint8_t clobber_buf[BLOCK_SIZE];
|
||||||
memset(clobber_buf, 0xcc, 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)))) {
|
if (!(seen[block / 8] & (1 << (block % 8)))) {
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
|
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
|
||||||
@@ -239,42 +239,42 @@ code = '''
|
|||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
if (remount) {
|
if (remount) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 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];
|
char name[256];
|
||||||
sprintf(name, "dir%03x", i);
|
sprintf(name, "dir%03x", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
lfs3_dir_open(&lfs3, &dir, "/") => 0;
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
lfs3_dir_read(&lfs3, &dir, &info) => 0;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
lfs3_dir_read(&lfs3, &dir, &info) => 0;
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
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];
|
char name[256];
|
||||||
sprintf(name, "dir%03x", i);
|
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(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
}
|
}
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
|
||||||
lfsr_dir_close(&lfs, &dir) => 0;
|
lfs3_dir_close(&lfs3, &dir) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.test_alloc_clobber_files]
|
[cases.test_alloc_clobber_files]
|
||||||
@@ -290,86 +290,86 @@ defines.SIZE = [
|
|||||||
]
|
]
|
||||||
defines.CKMETA = [false, true]
|
defines.CKMETA = [false, true]
|
||||||
defines.REMOUNT = [false, true]
|
defines.REMOUNT = [false, true]
|
||||||
in = 'lfs.c'
|
in = 'lfs3.c'
|
||||||
if = '(SIZE*N)/BLOCK_SIZE <= 32'
|
if = '(SIZE*N)/BLOCK_SIZE <= 32'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
|
|
||||||
// create this many files
|
// create this many files
|
||||||
uint32_t prng = 42;
|
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];
|
char name[256];
|
||||||
sprintf(name, "file%03x", i);
|
sprintf(name, "file%03x", i);
|
||||||
|
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_t file;
|
lfs3_file_t file;
|
||||||
lfsr_file_open(&lfs, &file, name,
|
lfs3_file_open(&lfs3, &file, name,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
|
||||||
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE;
|
lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfs3_file_close(&lfs3, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that our writes worked
|
// check that our writes worked
|
||||||
prng = 42;
|
prng = 42;
|
||||||
for (lfs_size_t i = 0; i < N; i++) {
|
for (lfs3_size_t i = 0; i < N; i++) {
|
||||||
// check with stat
|
// check with stat
|
||||||
char name[256];
|
char name[256];
|
||||||
sprintf(name, "file%03x", i);
|
sprintf(name, "file%03x", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS3_TYPE_REG);
|
||||||
assert(info.size == SIZE);
|
assert(info.size == SIZE);
|
||||||
|
|
||||||
// try reading the file, note we reset prng above
|
// try reading the file, note we reset prng above
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_t file;
|
lfs3_file_t file;
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
|
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
|
||||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfs3_file_close(&lfs3, &file) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remount?
|
// remount?
|
||||||
if (REMOUNT) {
|
if (REMOUNT) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first traverse the tree to find all blocks in use
|
// first traverse the tree to find all blocks in use
|
||||||
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
|
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
|
||||||
memset(seen, 0, (BLOCK_COUNT+7)/8);
|
memset(seen, 0, (BLOCK_COUNT+7)/8);
|
||||||
|
|
||||||
lfsr_traversal_t t;
|
lfs3_traversal_t t;
|
||||||
lfsr_traversal_init(&t,
|
lfs3_traversal_init(&t,
|
||||||
LFS_T_RDONLY
|
LFS3_T_RDONLY
|
||||||
| ((CKMETA) ? LFS_T_CKMETA : 0));
|
| ((CKMETA) ? LFS3_T_CKMETA : 0));
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs3_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
assert(i < 2*BLOCK_COUNT);
|
assert(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
lfsr_tag_t tag;
|
lfs3_tag_t tag;
|
||||||
lfsr_bptr_t bptr;
|
lfs3_bptr_t bptr;
|
||||||
int err = lfsr_mtree_traverse(&lfs, &t,
|
int err = lfs3_mtree_traverse(&lfs3, &t,
|
||||||
&tag, &bptr);
|
&tag, &bptr);
|
||||||
assert(!err || err == LFS_ERR_NOENT);
|
assert(!err || err == LFS3_ERR_NOENT);
|
||||||
if (err == LFS_ERR_NOENT) {
|
if (err == LFS3_ERR_NOENT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag == LFSR_TAG_MDIR) {
|
if (tag == LFS3_TAG_MDIR) {
|
||||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
|
||||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||||
tag,
|
tag,
|
||||||
mdir->rbyd.blocks[0],
|
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[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
|
||||||
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||||
|
|
||||||
} else if (tag == LFSR_TAG_BRANCH) {
|
} else if (tag == LFS3_TAG_BRANCH) {
|
||||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
|
||||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||||
tag,
|
tag,
|
||||||
rbyd->blocks[0], rbyd->trunk);
|
rbyd->blocks[0], rbyd->trunk);
|
||||||
@@ -388,7 +388,7 @@ code = '''
|
|||||||
// keep track of seen blocks
|
// keep track of seen blocks
|
||||||
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
|
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",
|
printf("traversal: 0x%x block 0x%x\n",
|
||||||
tag,
|
tag,
|
||||||
bptr.data.u.disk.block);
|
bptr.data.u.disk.block);
|
||||||
@@ -407,7 +407,7 @@ code = '''
|
|||||||
// then clobber every other block
|
// then clobber every other block
|
||||||
uint8_t clobber_buf[BLOCK_SIZE];
|
uint8_t clobber_buf[BLOCK_SIZE];
|
||||||
memset(clobber_buf, 0xcc, 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)))) {
|
if (!(seen[block / 8] & (1 << (block % 8)))) {
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
|
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
|
||||||
@@ -419,37 +419,37 @@ code = '''
|
|||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
if (remount) {
|
if (remount) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
prng = 42;
|
prng = 42;
|
||||||
for (lfs_size_t i = 0; i < N; i++) {
|
for (lfs3_size_t i = 0; i < N; i++) {
|
||||||
// check with stat
|
// check with stat
|
||||||
char name[256];
|
char name[256];
|
||||||
sprintf(name, "file%03x", i);
|
sprintf(name, "file%03x", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS3_TYPE_REG);
|
||||||
assert(info.size == SIZE);
|
assert(info.size == SIZE);
|
||||||
|
|
||||||
// try reading the file, note we reset prng above
|
// try reading the file, note we reset prng above
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_t file;
|
lfs3_file_t file;
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
|
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
|
||||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
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
|
# open files need to be tracked internally to make sure this doesn't break
|
||||||
@@ -465,42 +465,42 @@ defines.SIZE = [
|
|||||||
'8*BLOCK_SIZE',
|
'8*BLOCK_SIZE',
|
||||||
]
|
]
|
||||||
defines.CKMETA = [false, true]
|
defines.CKMETA = [false, true]
|
||||||
in = 'lfs.c'
|
in = 'lfs3.c'
|
||||||
if = '(SIZE*N)/BLOCK_SIZE <= 32'
|
if = '(SIZE*N)/BLOCK_SIZE <= 32'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
|
|
||||||
// create this many files
|
// create this many files
|
||||||
lfsr_file_t files[N];
|
lfs3_file_t files[N];
|
||||||
uint32_t prng = 42;
|
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];
|
char name[256];
|
||||||
sprintf(name, "file%03x", i);
|
sprintf(name, "file%03x", i);
|
||||||
|
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_open(&lfs, &files[i], name,
|
lfs3_file_open(&lfs3, &files[i], name,
|
||||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS3_O_RDWR | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
|
||||||
lfsr_file_write(&lfs, &files[i], wbuf, SIZE) => SIZE;
|
lfs3_file_write(&lfs3, &files[i], wbuf, SIZE) => SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that our writes worked
|
// check that our writes worked
|
||||||
prng = 42;
|
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
|
// try reading the file, note we reset prng above
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
lfsr_file_rewind(&lfs, &files[i]) => 0;
|
lfs3_file_rewind(&lfs3, &files[i]) => 0;
|
||||||
lfsr_file_read(&lfs, &files[i], rbuf, SIZE) => SIZE;
|
lfs3_file_read(&lfs3, &files[i], rbuf, SIZE) => SIZE;
|
||||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,25 +508,25 @@ code = '''
|
|||||||
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
|
uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
|
||||||
memset(seen, 0, (BLOCK_COUNT+7)/8);
|
memset(seen, 0, (BLOCK_COUNT+7)/8);
|
||||||
|
|
||||||
lfsr_traversal_t t;
|
lfs3_traversal_t t;
|
||||||
lfsr_traversal_init(&t,
|
lfs3_traversal_init(&t,
|
||||||
LFS_T_RDONLY
|
LFS3_T_RDONLY
|
||||||
| ((CKMETA) ? LFS_T_CKMETA : 0));
|
| ((CKMETA) ? LFS3_T_CKMETA : 0));
|
||||||
for (lfs_block_t i = 0;; i++) {
|
for (lfs3_block_t i = 0;; i++) {
|
||||||
// a bit hacky, but this catches infinite loops
|
// a bit hacky, but this catches infinite loops
|
||||||
assert(i < 2*BLOCK_COUNT);
|
assert(i < 2*BLOCK_COUNT);
|
||||||
|
|
||||||
lfsr_tag_t tag;
|
lfs3_tag_t tag;
|
||||||
lfsr_bptr_t bptr;
|
lfs3_bptr_t bptr;
|
||||||
int err = lfsr_mtree_traverse(&lfs, &t,
|
int err = lfs3_mtree_traverse(&lfs3, &t,
|
||||||
&tag, &bptr);
|
&tag, &bptr);
|
||||||
assert(!err || err == LFS_ERR_NOENT);
|
assert(!err || err == LFS3_ERR_NOENT);
|
||||||
if (err == LFS_ERR_NOENT) {
|
if (err == LFS3_ERR_NOENT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag == LFSR_TAG_MDIR) {
|
if (tag == LFS3_TAG_MDIR) {
|
||||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
|
||||||
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
printf("traversal: 0x%x mdir 0x{%x,%x}\n",
|
||||||
tag,
|
tag,
|
||||||
mdir->rbyd.blocks[0],
|
mdir->rbyd.blocks[0],
|
||||||
@@ -538,8 +538,8 @@ code = '''
|
|||||||
seen[mdir->rbyd.blocks[0] / 8]
|
seen[mdir->rbyd.blocks[0] / 8]
|
||||||
|= 1 << (mdir->rbyd.blocks[0] % 8);
|
|= 1 << (mdir->rbyd.blocks[0] % 8);
|
||||||
|
|
||||||
} else if (tag == LFSR_TAG_BRANCH) {
|
} else if (tag == LFS3_TAG_BRANCH) {
|
||||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
|
||||||
printf("traversal: 0x%x btree 0x%x.%x\n",
|
printf("traversal: 0x%x btree 0x%x.%x\n",
|
||||||
tag,
|
tag,
|
||||||
rbyd->blocks[0], rbyd->trunk);
|
rbyd->blocks[0], rbyd->trunk);
|
||||||
@@ -548,7 +548,7 @@ code = '''
|
|||||||
seen[rbyd->blocks[0] / 8]
|
seen[rbyd->blocks[0] / 8]
|
||||||
|= 1 << (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",
|
printf("traversal: 0x%x block 0x%x\n",
|
||||||
tag,
|
tag,
|
||||||
bptr.data.u.disk.block);
|
bptr.data.u.disk.block);
|
||||||
@@ -567,7 +567,7 @@ code = '''
|
|||||||
// then clobber every other block
|
// then clobber every other block
|
||||||
uint8_t clobber_buf[BLOCK_SIZE];
|
uint8_t clobber_buf[BLOCK_SIZE];
|
||||||
memset(clobber_buf, 0xcc, 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)))) {
|
if (!(seen[block / 8] & (1 << (block % 8)))) {
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 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
|
// then check that reading our files still works after clobbering
|
||||||
prng = 42;
|
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
|
// try reading the file, note we reset prng above
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
lfsr_file_rewind(&lfs, &files[i]) => 0;
|
lfs3_file_rewind(&lfs3, &files[i]) => 0;
|
||||||
lfsr_file_read(&lfs, &files[i], rbuf, SIZE) => SIZE;
|
lfs3_file_read(&lfs3, &files[i], rbuf, SIZE) => SIZE;
|
||||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and everything is fine after saving the files
|
// and everything is fine after saving the files
|
||||||
for (lfs_size_t i = 0; i < N; i++) {
|
for (lfs3_size_t i = 0; i < N; i++) {
|
||||||
lfsr_file_close(&lfs, &files[i]) => 0;
|
lfs3_file_close(&lfs3, &files[i]) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
if (remount) {
|
if (remount) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
prng = 42;
|
prng = 42;
|
||||||
for (lfs_size_t i = 0; i < N; i++) {
|
for (lfs3_size_t i = 0; i < N; i++) {
|
||||||
// check with stat
|
// check with stat
|
||||||
char name[256];
|
char name[256];
|
||||||
sprintf(name, "file%03x", i);
|
sprintf(name, "file%03x", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS3_TYPE_REG);
|
||||||
assert(info.size == SIZE);
|
assert(info.size == SIZE);
|
||||||
|
|
||||||
// try reading the file, note we reset prng above
|
// try reading the file, note we reset prng above
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_t file;
|
lfs3_file_t file;
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
|
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
|
||||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
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 = '''
|
code = '''
|
||||||
// test various block counts
|
// test various block counts
|
||||||
struct lfs_config cfg = *CFG;
|
struct lfs3_config cfg = *CFG;
|
||||||
cfg.block_count = COUNT;
|
cfg.block_count = COUNT;
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
|
||||||
|
|
||||||
// create directories until we run out of space
|
// create directories until we run out of space
|
||||||
lfs_size_t n = 0;
|
lfs3_size_t n = 0;
|
||||||
for (;; n++) {
|
for (;; n++) {
|
||||||
char name[256];
|
char name[256];
|
||||||
sprintf(name, "dir%08d", n);
|
sprintf(name, "dir%08d", n);
|
||||||
int err = lfsr_mkdir(&lfs, name);
|
int err = lfs3_mkdir(&lfs3, name);
|
||||||
assert(!err || err == LFS_ERR_NOSPC);
|
assert(!err || err == LFS3_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS3_ERR_NOSPC) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -668,45 +668,45 @@ code = '''
|
|||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
if (remount) {
|
if (remount) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that our mkdir worked until we ran out of space
|
// 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];
|
char name[256];
|
||||||
sprintf(name, "dir%08d", i);
|
sprintf(name, "dir%08d", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_dir_t dir;
|
lfs3_dir_t dir;
|
||||||
lfsr_dir_open(&lfs, &dir, "/") => 0;
|
lfs3_dir_open(&lfs3, &dir, "/") => 0;
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
lfs3_dir_read(&lfs3, &dir, &info) => 0;
|
||||||
assert(strcmp(info.name, ".") == 0);
|
assert(strcmp(info.name, ".") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
lfs3_dir_read(&lfs3, &dir, &info) => 0;
|
||||||
assert(strcmp(info.name, "..") == 0);
|
assert(strcmp(info.name, "..") == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
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];
|
char name[256];
|
||||||
sprintf(name, "dir%08d", i);
|
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(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_DIR);
|
assert(info.type == LFS3_TYPE_DIR);
|
||||||
assert(info.size == 0);
|
assert(info.size == 0);
|
||||||
}
|
}
|
||||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
|
||||||
lfsr_dir_close(&lfs, &dir) => 0;
|
lfs3_dir_close(&lfs3, &dir) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.test_alloc_nospc_files]
|
[cases.test_alloc_nospc_files]
|
||||||
@@ -729,42 +729,42 @@ defines.SIZE = [
|
|||||||
]
|
]
|
||||||
code = '''
|
code = '''
|
||||||
// test various block counts
|
// test various block counts
|
||||||
struct lfs_config cfg = *CFG;
|
struct lfs3_config cfg = *CFG;
|
||||||
cfg.block_count = COUNT;
|
cfg.block_count = COUNT;
|
||||||
lfs_t lfs;
|
lfs3_t lfs3;
|
||||||
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0;
|
lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
|
||||||
|
|
||||||
// create files until we run out of space
|
// create files until we run out of space
|
||||||
uint32_t prng = 42;
|
uint32_t prng = 42;
|
||||||
lfs_size_t n = 0;
|
lfs3_size_t n = 0;
|
||||||
for (;; n++) {
|
for (;; n++) {
|
||||||
char name[256];
|
char name[256];
|
||||||
sprintf(name, "file%08d", n);
|
sprintf(name, "file%08d", n);
|
||||||
|
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_t file;
|
lfs3_file_t file;
|
||||||
int err = lfsr_file_open(&lfs, &file, name,
|
int err = lfs3_file_open(&lfs3, &file, name,
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL);
|
LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL);
|
||||||
assert(!err || err == LFS_ERR_NOSPC);
|
assert(!err || err == LFS3_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS3_ERR_NOSPC) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_ssize_t size = lfsr_file_write(&lfs, &file, wbuf, SIZE);
|
lfs3_ssize_t size = lfs3_file_write(&lfs3, &file, wbuf, SIZE);
|
||||||
assert(size == SIZE || size == LFS_ERR_NOSPC);
|
assert(size == SIZE || size == LFS3_ERR_NOSPC);
|
||||||
if (size == LFS_ERR_NOSPC) {
|
if (size == LFS3_ERR_NOSPC) {
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfs3_file_close(&lfs3, &file) => 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfsr_file_close(&lfs, &file);
|
err = lfs3_file_close(&lfs3, &file);
|
||||||
assert(!err || err == LFS_ERR_NOSPC);
|
assert(!err || err == LFS3_ERR_NOSPC);
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS3_ERR_NOSPC) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -772,37 +772,37 @@ code = '''
|
|||||||
for (int remount = 0; remount < 2; remount++) {
|
for (int remount = 0; remount < 2; remount++) {
|
||||||
// remount?
|
// remount?
|
||||||
if (remount) {
|
if (remount) {
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfs3_unmount(&lfs3) => 0;
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0;
|
lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that our file writes worked until we ran out of space
|
// check that our file writes worked until we ran out of space
|
||||||
prng = 42;
|
prng = 42;
|
||||||
for (lfs_size_t i = 0; i < n; i++) {
|
for (lfs3_size_t i = 0; i < n; i++) {
|
||||||
// check with stat
|
// check with stat
|
||||||
char name[256];
|
char name[256];
|
||||||
sprintf(name, "file%08d", i);
|
sprintf(name, "file%08d", i);
|
||||||
struct lfs_info info;
|
struct lfs3_info info;
|
||||||
lfsr_stat(&lfs, name, &info) => 0;
|
lfs3_stat(&lfs3, name, &info) => 0;
|
||||||
assert(strcmp(info.name, name) == 0);
|
assert(strcmp(info.name, name) == 0);
|
||||||
assert(info.type == LFS_TYPE_REG);
|
assert(info.type == LFS3_TYPE_REG);
|
||||||
assert(info.size == SIZE);
|
assert(info.size == SIZE);
|
||||||
|
|
||||||
// try reading the file, note we reset prng above
|
// try reading the file, note we reset prng above
|
||||||
uint8_t wbuf[SIZE];
|
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);
|
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_t file;
|
lfs3_file_t file;
|
||||||
uint8_t rbuf[SIZE];
|
uint8_t rbuf[SIZE];
|
||||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0;
|
lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
|
||||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
|
||||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
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.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
||||||
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t buffer[LFS_MAX(READ, PROG)];
|
uint8_t buffer[LFS3_MAX(READ, PROG)];
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
CFG->erase(CFG, 0) => 0;
|
CFG->erase(CFG, 0) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (i+j) % 251;
|
buffer[j] = (i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, 0, i, buffer, PROG) => 0;
|
CFG->prog(CFG, 0, i, buffer, PROG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read data
|
// 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;
|
CFG->read(CFG, 0, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
@@ -35,14 +35,14 @@ code = '''
|
|||||||
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
||||||
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t buffer[LFS_MAX(READ, PROG)];
|
uint8_t buffer[LFS3_MAX(READ, PROG)];
|
||||||
lfs_block_t block;
|
lfs3_block_t block;
|
||||||
|
|
||||||
// write block 0
|
// write block 0
|
||||||
block = 0;
|
block = 0;
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (block+i+j) % 251;
|
buffer[j] = (block+i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
||||||
@@ -50,19 +50,19 @@ code = '''
|
|||||||
|
|
||||||
// read block 0
|
// read block 0
|
||||||
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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write block 1
|
// write block 1
|
||||||
block = 1;
|
block = 1;
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (block+i+j) % 251;
|
buffer[j] = (block+i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
||||||
@@ -70,21 +70,21 @@ code = '''
|
|||||||
|
|
||||||
// read block 1
|
// read block 1
|
||||||
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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read block 0 again
|
// read block 0 again
|
||||||
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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
@@ -93,14 +93,14 @@ code = '''
|
|||||||
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
||||||
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t buffer[LFS_MAX(READ, PROG)];
|
uint8_t buffer[LFS3_MAX(READ, PROG)];
|
||||||
lfs_block_t block;
|
lfs3_block_t block;
|
||||||
|
|
||||||
// write block 0
|
// write block 0
|
||||||
block = 0;
|
block = 0;
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (block+i+j) % 251;
|
buffer[j] = (block+i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
||||||
@@ -108,19 +108,19 @@ code = '''
|
|||||||
|
|
||||||
// read block 0
|
// read block 0
|
||||||
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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write block n-1
|
// write block n-1
|
||||||
block = CFG->block_count-1;
|
block = CFG->block_count-1;
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (block+i+j) % 251;
|
buffer[j] = (block+i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
||||||
@@ -128,21 +128,21 @@ code = '''
|
|||||||
|
|
||||||
// read block n-1
|
// read block n-1
|
||||||
block = CFG->block_count-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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read block 0 again
|
// read block 0 again
|
||||||
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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
@@ -151,26 +151,26 @@ code = '''
|
|||||||
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
||||||
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t buffer[LFS_MAX(READ, PROG)];
|
uint8_t buffer[LFS3_MAX(READ, PROG)];
|
||||||
|
|
||||||
// write/read every power of 2
|
// write/read every power of 2
|
||||||
lfs_block_t block = 1;
|
lfs3_block_t block = 1;
|
||||||
while (block < CFG->block_count) {
|
while (block < CFG->block_count) {
|
||||||
// write
|
// write
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (block+i+j) % 251;
|
buffer[j] = (block+i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read
|
// 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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,11 +181,11 @@ code = '''
|
|||||||
block = 1;
|
block = 1;
|
||||||
while (block < CFG->block_count) {
|
while (block < CFG->block_count) {
|
||||||
// read
|
// 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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,31 +197,31 @@ code = '''
|
|||||||
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
|
||||||
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
|
||||||
code = '''
|
code = '''
|
||||||
uint8_t buffer[LFS_MAX(READ, PROG)];
|
uint8_t buffer[LFS3_MAX(READ, PROG)];
|
||||||
|
|
||||||
// write/read every fibonacci number on our device
|
// write/read every fibonacci number on our device
|
||||||
lfs_block_t block = 1;
|
lfs3_block_t block = 1;
|
||||||
lfs_block_t block_ = 1;
|
lfs3_block_t block_ = 1;
|
||||||
while (block < CFG->block_count) {
|
while (block < CFG->block_count) {
|
||||||
// write
|
// write
|
||||||
CFG->erase(CFG, block) => 0;
|
CFG->erase(CFG, block) => 0;
|
||||||
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) {
|
for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
|
||||||
for (lfs_off_t j = 0; j < PROG; j++) {
|
for (lfs3_off_t j = 0; j < PROG; j++) {
|
||||||
buffer[j] = (block+i+j) % 251;
|
buffer[j] = (block+i+j) % 251;
|
||||||
}
|
}
|
||||||
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
CFG->prog(CFG, block, i, buffer, PROG) => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read
|
// 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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_block_t nblock = block + block_;
|
lfs3_block_t nblock = block + block_;
|
||||||
block_ = block;
|
block_ = block;
|
||||||
block = nblock;
|
block = nblock;
|
||||||
}
|
}
|
||||||
@@ -231,15 +231,15 @@ code = '''
|
|||||||
block_ = 1;
|
block_ = 1;
|
||||||
while (block < CFG->block_count) {
|
while (block < CFG->block_count) {
|
||||||
// read
|
// 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;
|
CFG->read(CFG, block, i, buffer, READ) => 0;
|
||||||
|
|
||||||
for (lfs_off_t j = 0; j < READ; j++) {
|
for (lfs3_off_t j = 0; j < READ; j++) {
|
||||||
LFS_ASSERT(buffer[j] == (block+i+j) % 251);
|
LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_block_t nblock = block + block_;
|
lfs3_block_t nblock = block + block_;
|
||||||
block_ = block;
|
block_ = block;
|
||||||
block = nblock;
|
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