From 7cc87a4fe6fe84390c9bebb5522b1e8a4bd711e6 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 5 Jun 2025 18:02:57 -0500 Subject: [PATCH] rdonly: Dropped file.b.shrub_ when LFS3_RDONLY We don't need the staging shrub if we never stage shrubs! The only hangup was reuse of the staging shrub to load bshrubs/btrees in lfs3_file_fetch (we need to be able to fallback to the previous shrub if we error in lfs3_file_resync), but this can be handled with a stack allocated shrub. If btree-leaf-caches make a return, we would need to stack allocate this anyways due to the lopsided cost of the main/staging btrees/bshrubs introduced to avoid wasting space on the useless staging-shrub-leaf-cache. This saves some code in LFS3_RDONLY, and apparently an instruction or two in the default build (I guess stack loads/stores are cheaper?): code stack ctx rdonly before: 10680 840 524 rdonly after: 10640 (-0.4%) 816 (+0.0%) 524 (+0.0%) default before: 37324 2280 636 default after: 37320 (-0.0%) 2280 (+0.0%) 636 (+0.0%) It's not apparent in ctx because lfs3_info.name dominates (guh), but this does save some RAM in lfs3_file_t: rdonly ctx lfs3_file_t before: 136 lfs3_file_t after: 112 (-17.6%) It does add some stack cost to lfs3_file_fetch, but because this isn't on the stack hot-path in either build, we don't really care: default code stack ctx lfs3_file_fetch before: 372 416 0 lfs3_file_fetch after: 368 (-1.1%) 440 (+5.8%) 0 (+0.0%) --- lfs3.c | 10 +++++----- lfs3.h | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lfs3.c b/lfs3.c index 8a7b88d3..2ff44f0b 100644 --- a/lfs3.c +++ b/lfs3.c @@ -11341,15 +11341,15 @@ static int lfs3_file_fetch(lfs3_t *lfs3, lfs3_file_t *file, bool trunc) { } // note many of these functions leave bshrub undefined if there - // is an error, so we first read into the staging bshrub - file->b.shrub_ = file->b.shrub; + // is an error, so we first read into a temporary bshrub/btree + lfs3_rbyd_t shrub = file->b.shrub; // found a bshrub/btree? if (err != LFS3_ERR_NOENT) { // may be a bshrub (inlined btree) if (tag == LFS3_TAG_BSHRUB) { err = lfs3_data_readshrub(lfs3, &data, &file->b.o.mdir, - &file->b.shrub_); + &shrub); if (err) { return err; } @@ -11357,7 +11357,7 @@ static int lfs3_file_fetch(lfs3_t *lfs3, lfs3_file_t *file, bool trunc) { // or a btree } else if (tag == LFS3_TAG_BTREE) { err = lfs3_data_fetchbtree(lfs3, &data, - &file->b.shrub_); + &shrub); if (err) { return err; } @@ -11368,7 +11368,7 @@ static int lfs3_file_fetch(lfs3_t *lfs3, lfs3_file_t *file, bool trunc) { } // update the bshrub/btree - file->b.shrub = file->b.shrub_; + file->b.shrub = shrub; // mark as in-sync file->b.o.flags &= ~LFS3_o_UNSYNC; diff --git a/lfs3.h b/lfs3.h index 4e062bc2..ecd5f034 100644 --- a/lfs3.h +++ b/lfs3.h @@ -720,8 +720,9 @@ typedef struct lfs3_bshrub { // sign(trunk)=1 => bshrub // sign(trunk)=0 => btree lfs3_shrub_t shrub; - // TODO can we actually get rid of shrub_ when LFS3_RDONLY? + #ifndef LFS3_RDONLY lfs3_shrub_t shrub_; + #endif } lfs3_bshrub_t; // littlefs file type