Changed bshrub functions to operate on mdir+bshrub directly

This gets a bit messy, since lfsr_bshrub_commit really requires the
bshrub to be enrolled in the opened mdir list to stage correctly.

To make this work, our internal SHRUBCOMMIT and SHRUBTRUNK attrs now
take a pointer to the active shrub, and assume it is followed by a
staging shrub in memory. This is a big hack/assumption that leaks
through lfsr_bshrub_commit, but it at gets the job done in our current
system.

Note some functions were renamed instead, these didn't really make sense
as pure-bshrub functions:

- lfsr_bshrub_readnext -> lfsr_file_readnext
- lfsr_bshrub_read -> lfsr_file_read_

---

The main reason for this is to comply with C99's strict aliasing rules,
which can be a real PIA sometimes.

We need to track a bshrub in lfsr_mtraversal_t, but we really don't want
to pay the RAM cost for an entire lfsr_file_t. The best option I've
found is to pass around multiple pointers to the relevant internal
structs (mdir+bshrub), but this adds a stack+code cost.

So far, strict aliasing is a net downside:

                         code          stack
  before:               34478           2624
  -fno-strict-aliasing: 34502 (+0.1%)   2616 (-0.3%)
  after:                34566 (+0.3%)   2632 (+0.3%)

But it's baked into the standard and we can't always rely on
-fno-strict-aliasing being available.
This commit is contained in:
Christopher Haster
2024-06-23 13:05:06 -05:00
parent d155750f14
commit 55d9f5c76a
2 changed files with 120 additions and 99 deletions
+3 -7
View File
@@ -605,14 +605,10 @@ typedef struct lfsr_btraversal {
typedef struct lfsr_mtraversal {
// core state machine in o.state
lfsr_omdir_t o;
// we really don't want to pay the RAM cost for a full file,
// so only store the relevant bits, is this a hack? yes
const struct lfs_file_config *cfg;
lfsr_bshrub_t bshrub;
// opened file state, we use an indirect pointer here so we
// always point to data associated with the current mid
// opened file state
lfsr_omdir_t *ot;
// bshrub/btree state
lfsr_bshrub_t bshrub;
union {
// cycle detection state, only valid when traversing the mroot chain
struct {