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%)
This commit is contained in:
@@ -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
|
// note many of these functions leave bshrub undefined if there
|
||||||
// is an error, so we first read into the staging bshrub
|
// is an error, so we first read into a temporary bshrub/btree
|
||||||
file->b.shrub_ = file->b.shrub;
|
lfs3_rbyd_t shrub = file->b.shrub;
|
||||||
|
|
||||||
// found a bshrub/btree?
|
// found a bshrub/btree?
|
||||||
if (err != LFS3_ERR_NOENT) {
|
if (err != LFS3_ERR_NOENT) {
|
||||||
// may be a bshrub (inlined btree)
|
// may be a bshrub (inlined btree)
|
||||||
if (tag == LFS3_TAG_BSHRUB) {
|
if (tag == LFS3_TAG_BSHRUB) {
|
||||||
err = lfs3_data_readshrub(lfs3, &data, &file->b.o.mdir,
|
err = lfs3_data_readshrub(lfs3, &data, &file->b.o.mdir,
|
||||||
&file->b.shrub_);
|
&shrub);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -11357,7 +11357,7 @@ static int lfs3_file_fetch(lfs3_t *lfs3, lfs3_file_t *file, bool trunc) {
|
|||||||
// or a btree
|
// or a btree
|
||||||
} else if (tag == LFS3_TAG_BTREE) {
|
} else if (tag == LFS3_TAG_BTREE) {
|
||||||
err = lfs3_data_fetchbtree(lfs3, &data,
|
err = lfs3_data_fetchbtree(lfs3, &data,
|
||||||
&file->b.shrub_);
|
&shrub);
|
||||||
if (err) {
|
if (err) {
|
||||||
return 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
|
// update the bshrub/btree
|
||||||
file->b.shrub = file->b.shrub_;
|
file->b.shrub = shrub;
|
||||||
|
|
||||||
// mark as in-sync
|
// mark as in-sync
|
||||||
file->b.o.flags &= ~LFS3_o_UNSYNC;
|
file->b.o.flags &= ~LFS3_o_UNSYNC;
|
||||||
|
|||||||
@@ -720,8 +720,9 @@ typedef struct lfs3_bshrub {
|
|||||||
// sign(trunk)=1 => bshrub
|
// sign(trunk)=1 => bshrub
|
||||||
// sign(trunk)=0 => btree
|
// sign(trunk)=0 => btree
|
||||||
lfs3_shrub_t shrub;
|
lfs3_shrub_t shrub;
|
||||||
// TODO can we actually get rid of shrub_ when LFS3_RDONLY?
|
#ifndef LFS3_RDONLY
|
||||||
lfs3_shrub_t shrub_;
|
lfs3_shrub_t shrub_;
|
||||||
|
#endif
|
||||||
} lfs3_bshrub_t;
|
} lfs3_bshrub_t;
|
||||||
|
|
||||||
// littlefs file type
|
// littlefs file type
|
||||||
|
|||||||
Reference in New Issue
Block a user