t: Changed lfsr_mtree_traverse to operate on mdir+mtraversal

Separated out omdir/mdir and mtraversal. You still need to allocate an
mdir for mtraversal to work, but this avoids the extra cost of omdir's
linked-list.

To avoid _too_ many pointers, I duplicated the flags field into both
lfsr_traversal_t and lfsr_mtraversal_t. This is basically free since we
end up with a bunch of padding for mtraversal's state field, but comes
with the risk of getting confused when the two flag fields don't match
in the future.

I also merged the intermediary btype field into flags to avoid yet
another single-byte field, where it fits comfortably in 3-bits.

Note that the mdir can be uninitialized in cases where we don't need to
worry about traversal clobbering.

---

This has the same problems as separating out mdirs/bshrubs in bshrub
functions: more stack/code to move the multiple pointers around, but is
necessary to avoid strict aliasing issues. There's no way to represent
overlapping omdir/mdir/mtraversal struct in standard C99 otherwise.

The end result saves a bit of code, but adds a bit of stack:

           code          stack
  before: 34576           2632
  after:  34524 (-0.2%)   2640 (+0.3%)

Though these numbers may be close enough to the compiler noise floor to
not really care about...
This commit is contained in:
Christopher Haster
2024-06-23 23:21:34 -05:00
parent b383821a22
commit 2f1d711902
4 changed files with 151 additions and 149 deletions
+5 -6
View File
@@ -474,7 +474,6 @@ typedef struct lfsr_mdir {
typedef struct lfsr_omdir {
struct lfsr_omdir *next;
uint8_t type;
uint8_t state;
uint16_t flags;
lfsr_mdir_t mdir;
} lfsr_omdir_t;
@@ -603,10 +602,11 @@ typedef struct lfsr_btraversal {
} lfsr_btraversal_t;
typedef struct lfsr_mtraversal {
// core state machine in o.state
lfsr_omdir_t o;
// core state machine
uint8_t state;
uint16_t flags;
// opened file state
lfsr_omdir_t *ot;
lfsr_omdir_t *o;
// bshrub/btree state
lfsr_bshrub_t bshrub;
union {
@@ -622,9 +622,8 @@ typedef struct lfsr_mtraversal {
} lfsr_mtraversal_t;
typedef struct lfsr_traversal {
// lfsr_mtraversal_t contains most of what we need
lfsr_omdir_t o;
lfsr_mtraversal_t mt;
uint8_t btype;
lfs_sblock_t blocks[2];
} lfsr_traversal_t;