rdonly: Dropped rbyd.eoff when LFS3_RDONLY

rbyd.eoff has the relatively unique property of only being useful in
rdwr mode. In rdonly mode we don't care where the next erased-state
starts because we're never going to use it.

Since rbyds are used everywhere, dropping rbyd.eoff has the potential to
save a significant amount of RAM.

---

At least on paper. We were using the field in lfs3_rbyd_fetch to keep
track of the most recent valid commit perturb/eoff, which was a bit
tricky to disentangle.

Disentangling lfs3_rbyd_fetch does add a bit of code to the default
build, but saves code, stack, and ctx in the rdonly mode:

                   code          stack          ctx
  rdonly before:  10640            816          524
  rdonly after:   10616 (-0.2%)    808 (-1.0%)  508 (-3.1%)

  default before: 37320           2280          636
  default after:  37352 (+0.1%)   2280 (+0.0%)  636 (+0.0%)

In theory we could ifdef the crap out of lfs3_rbyd_fetch to claw back
this code, but 1. 32 bytes of code is really not that much code, 2. the
more rdonly and default diverge the more likely rdonly breaks, and 3. I
think the new code is a bit more readable since it avoids masking
perturb/eoff together until the last minute.
This commit is contained in:
Christopher Haster
2025-06-05 19:41:43 -05:00
parent 7cc87a4fe6
commit 0096305968
2 changed files with 79 additions and 56 deletions
+2 -1
View File
@@ -682,12 +682,13 @@ typedef struct lfs3_rbyd {
// sign(trunk)=0 => normal rbyd
// sign(trunk)=1 => shrub rbyd
lfs3_size_t trunk;
// TODO can we actually get rid of eoff when LFS3_RDONLY?
#ifndef LFS3_RDONLY
// sign(eoff) => perturb bit
// eoff=0, trunk=0 => not yet committed
// eoff=0, trunk>0 => not yet fetched
// eoff>=block_size => rbyd not erased/needs compaction
lfs3_size_t eoff;
#endif
uint32_t cksum;
} lfs3_rbyd_t;