gc: Moved incremental gc behind ifdef LFS_GC

Incremental gc, being stateful and not gc-able (ironic), was always
going to need to be conditionally compilable.

This moves incremental gc behind the LFS_GC define, so that we can focus
on the "default" costs. This cuts lfs_t in nearly half!

  lfs_t with LFS_GC:   308
  lfs_t without LFS_C: 168 (-45.5%)

This does save less code than one might expect though. We still need
most of the internal traversal/gc logic for things like block allocation
and orphan cleanup, so most of the savings is limited to the RAM storing
the incremental state:

                          code          stack          ctx
  before:                37916           2608          768
  after with LFS_CFG:    37944 (+0.1%)   2608 (+0.0%)  768 (+0.0%)
  after without LFS_CFG: 37796 (-0.3%)   2608 (+0.0%)  620 (-19.3%)

On the flip side, this does mean most of the incremental gc
functionality is still availables in the lfsr_traversal_t APIs.

Applications with more advanced gc use-cases may actually benefit from
_not_ enabling the incremental gc APIs, and instead use the
lfsr_traversal_t APIs directly.
This commit is contained in:
Christopher Haster
2025-01-06 20:34:40 -06:00
parent 5d756fe698
commit 1b3054db89
8 changed files with 220 additions and 125 deletions
+9
View File
@@ -493,6 +493,7 @@ defines.COMPACT = [false, true]
defines.GC_FLAGS = 'LFS_GC_COMPACT'
defines.GC_STEPS = -1
defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2'
if = 'LFS_IFDEF_GC(true, !COMPACT)'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -528,9 +529,11 @@ code = '''
}
// try compacting?
#ifdef LFS_GC
if (COMPACT) {
lfsr_gc(&lfs) => 0;
}
#endif
for (int remount = 0; remount < 2; remount++) {
// remount?
@@ -572,6 +575,7 @@ defines.COMPACT = [false, true]
defines.GC_FLAGS = 'LFS_GC_COMPACT'
defines.GC_STEPS = -1
defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2'
if = 'LFS_IFDEF_GC(true, !COMPACT)'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -608,9 +612,11 @@ code = '''
}
// try compacting?
#ifdef LFS_GC
if (COMPACT) {
lfsr_gc(&lfs) => 0;
}
#endif
for (int remount = 0; remount < 2; remount++) {
// remount?
@@ -4074,6 +4080,7 @@ defines.COMPACT = [false, true]
defines.GC_FLAGS = 'LFS_GC_COMPACT'
defines.GC_STEPS = -1
defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2'
if = 'LFS_IFDEF_GC(true, !COMPACT)'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -4110,9 +4117,11 @@ code = '''
}
// try compacting?
#ifdef LFS_GC
if (COMPACT) {
lfsr_gc(&lfs) => 0;
}
#endif
for (int remount = 0; remount < 2; remount++) {
// remount?
+16 -2
View File
@@ -24,7 +24,10 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
if = '(SIZE*N)/BLOCK_SIZE <= 32'
if = [
'(SIZE*N)/BLOCK_SIZE <= 32',
'LFS_IFDEF_GC(true, METHOD != 1)',
]
code = '''
lfs_block_t i = 0;
while (true) {
@@ -98,7 +101,11 @@ code = '''
// find clobbered blocks with lfsr_gc
} else if (METHOD == 1) {
#ifdef LFS_GC
lfsr_gc(&lfs) => LFS_ERR_CORRUPT;
#else
LFS_UNREACHABLE();
#endif
// find clobbered blocks with lfsr_traversal_read
} else if (METHOD == 2) {
@@ -154,7 +161,10 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
if = '(SIZE*N)/BLOCK_SIZE <= 32'
if = [
'(SIZE*N)/BLOCK_SIZE <= 32',
'LFS_IFDEF_GC(true, METHOD != 1)',
]
code = '''
lfs_block_t i = 0;
while (true) {
@@ -229,7 +239,11 @@ code = '''
// find clobbered blocks with lfsr_gc
} else if (METHOD == 1) {
#ifdef LFS_GC
lfsr_gc(&lfs) => LFS_ERR_CORRUPT;
#else
LFS_UNREACHABLE();
#endif
// find clobbered blocks with lfsr_traversal_read
} else if (METHOD == 2) {
+27 -1
View File
@@ -22,6 +22,7 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -85,6 +86,7 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -153,6 +155,7 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -216,6 +219,7 @@ defines.SIZE = [
]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -290,6 +294,7 @@ defines.SIZE = [
]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -358,6 +363,7 @@ defines.SIZE = [
]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -430,6 +436,7 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -518,6 +525,7 @@ defines.SIZE = [
]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -618,6 +626,7 @@ defines.SIZE = [
]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -713,6 +722,7 @@ defines.SIZE = [
]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -804,6 +814,7 @@ defines.SIZE = 'FILE_BUFFER_SIZE/2'
# <=2 => grm-able
# >2 => requires orphans
defines.ORPHANS = [1, 2, 3, 100]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -953,7 +964,9 @@ code = '''
struct lfs_fsinfo fsinfo;
lfsr_fs_stat(&lfs, &fsinfo) => 0;
assert(fsinfo.flags & LFS_I_INCONSISTENT);
#ifdef LFS_GC
assert(lfs.omdirs != &lfs.gc.t.o.o);
#endif
// call lfsr_fs_mkconsistent
lfsr_fs_mkconsistent(&lfs) => 0;
@@ -1008,6 +1021,7 @@ defines.SIZE = 'FILE_BUFFER_SIZE/2'
defines.ORPHANS = [3, 100]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -1123,7 +1137,7 @@ defines.SIZE = 'FILE_BUFFER_SIZE/2'
defines.ORPHANS = [3, 100]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
in = 'lfs.c'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -1237,6 +1251,7 @@ defines.SIZE = 'FILE_BUFFER_SIZE/2'
defines.ORPHANS = [3, 100]
# we need something to keep the traversal running
if = 'CKMETA || CKDATA'
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -1349,6 +1364,7 @@ defines.SIZE = [
'8*BLOCK_SIZE',
]
if = '(SIZE*N)/BLOCK_SIZE <= 32'
ifdef = 'LFS_GC'
code = '''
lfs_block_t i = 0;
while (true) {
@@ -1448,6 +1464,7 @@ defines.SIZE = [
'8*BLOCK_SIZE',
]
if = '(SIZE*N)/BLOCK_SIZE <= 32'
ifdef = 'LFS_GC'
code = '''
lfs_block_t i = 0;
while (true) {
@@ -1740,6 +1757,7 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -1808,6 +1826,7 @@ defines.SIZE = [
'2*BLOCK_SIZE',
'8*BLOCK_SIZE',
]
ifdef = 'LFS_GC'
code = '''
lfs_t lfs;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0;
@@ -1876,6 +1895,7 @@ defines.GC_STEPS = [-1, 1, 2, 10, 100, 1000]
# set compact thresh to minimum
defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2'
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256]
ifdef = 'LFS_GC'
code = '''
// test creating directories
lfs_t lfs;
@@ -1976,6 +1996,7 @@ defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256]
defines.OPS = '2*N'
defines.SEED = 42
fuzz = 'SEED'
ifdef = 'LFS_GC'
code = '''
// test fuzz with dirs
lfs_t lfs;
@@ -2151,6 +2172,7 @@ defines.SIZE = [
'4*BLOCK_SIZE',
]
if = '(SIZE*N)/BLOCK_SIZE <= 32'
ifdef = 'LFS_GC'
code = '''
// test creating files
lfs_t lfs;
@@ -2245,6 +2267,7 @@ defines.SIZE = [
defines.SEED = 42
fuzz = 'SEED'
if = '(SIZE*N)/BLOCK_SIZE <= 16'
ifdef = 'LFS_GC'
code = '''
// test fuzz with files
lfs_t lfs;
@@ -2484,6 +2507,7 @@ if = [
# this just saves testing time
'SIZE <= 4*1024*FRAGMENT_SIZE',
]
ifdef = 'LFS_GC'
code = '''
// test with complex file writes
lfs_t lfs;
@@ -2625,6 +2649,7 @@ defines.SIZE = [
defines.SEED = 42
fuzz = 'SEED'
if = '(SIZE*N)/BLOCK_SIZE <= 16'
ifdef = 'LFS_GC'
code = '''
// test with uncreats, zombies, etc
lfs_t lfs;
@@ -2983,6 +3008,7 @@ defines.SIZE = [
defines.SEED = 42
fuzz = 'SEED'
if = '(SIZE*N)/BLOCK_SIZE <= 16'
ifdef = 'LFS_GC'
code = '''
// test with uncreats, zombies, dirs, etc
lfs_t lfs;