Adopt lfsr_ftree_t to help with staging files

lfsr_ftree_t acts as a sort of proto-file type, holding enough
information for file reads/writes if the relevant mdir is known.

This lets low-level file write operations operate on a copy of the
proto-file without needing to copy the relevant mdir, file stuff, etc.

To make this work, lfsr_mdir_commit also needs to stage any bshrubs in
the attr-list, since these may not be in our opened file list, but this
is a good thing to handle implicitly anyways. We should only ever have
one untracked bshrub being operated on (multithreaded support would be a
whole other can of worms).

Unfortunately the extra machinery in lfsr_mdir_commit, and the fact that
passing two pointers around instead of one adds quite a bit of code,
means this comes with a code cost. But the tradeoff for stack cost and
no risk of stack pointers in our opened file list makes this probably
worth it:

            code          stack
  before:  31584           2824
  after:   31760 (+0.6%)   2776 (-1.7%)
This commit is contained in:
Christopher Haster
2023-12-05 15:08:44 -06:00
parent 6bfbbae341
commit 166845f43f
2 changed files with 401 additions and 358 deletions
+389 -352
View File
File diff suppressed because it is too large Load Diff
+12 -6
View File
@@ -525,6 +525,17 @@ typedef struct lfsr_bshrub {
lfs_size_t progged;
} lfsr_bshrub_t;
// the lfsr_ftree_t struct is a sort of proto-file
typedef struct lfsr_ftree {
union {
lfs_soff_t size;
lfsr_bsprout_t bsprout;
lfsr_bptr_t bptr;
lfsr_bshrub_t bshrub;
lfsr_btree_t btree;
} u;
} lfsr_ftree_t;
typedef struct lfsr_file {
lfsr_openedmdir_t *next;
lfsr_mdir_t mdir;
@@ -536,12 +547,7 @@ typedef struct lfsr_file {
uint8_t *buffer;
lfs_size_t buffer_size;
union {
lfsr_bsprout_t bsprout;
lfsr_bptr_t bptr;
lfsr_bshrub_t bshrub;
lfsr_btree_t btree;
} u;
lfsr_ftree_t ftree;
const struct lfs_file_config *cfg;
} lfsr_file_t;