Generalized lfsr_file_crystallize_ for future write strategies

This function is actually pretty much the same in both the lazy and
eager crystallization write strategies. The main difference being the
nuances around the crystal_size parameter:

- lazy:  crystal_size => rough upper bound on crystal
- eager: crystal_size => strict lower bound on crystal

If we change these to an explicit crystal_min and crystal_max, we can
use lfsr_file_crystallize_ in both write strategies without changing the
logic.

It's out of scope right now, but this will help supporting both write
strategies in the future.

---

Unfortunately this added more code/stack that I was expecting:

           code          stack          ctx
  before: 36428           2248          636
  after:  36460 (+0.1%)   2280 (+1.4%)  636 (+0.0%)

I'm not exactly sure why, I guess the crystal_limit calculation is too
complex to const propagate the crystal_max=-1?

Maybe the LFS_NOINLINE is disabling certain cross-function
optimizations...
This commit is contained in:
Christopher Haster
2025-05-23 11:54:54 -05:00
parent 22c43124de
commit 9d6a94aa07

14
lfs.c
View File

@@ -12093,11 +12093,15 @@ static int lfsr_file_graft(lfs_t *lfs, lfsr_file_t *file,
// hot-path
LFS_NOINLINE
static int lfsr_file_crystallize_(lfs_t *lfs, lfsr_file_t *file,
lfs_off_t block_pos, lfs_soff_t crystal_size,
lfs_off_t block_pos, lfs_soff_t crystal_min, lfs_soff_t crystal_max,
lfs_off_t pos, const uint8_t *buffer, lfs_size_t size) {
// limit to block_size and theoretical file size
// align to prog_size, limit to block_size and theoretical file size
lfs_off_t crystal_limit = lfs_min(
block_pos + lfs->cfg->block_size,
block_pos + lfs_min(
lfs_aligndown(
(lfs_off_t)crystal_max,
lfs->cfg->prog_size),
lfs->cfg->block_size),
lfs_max(
pos + size,
file->b.shrub.weight));
@@ -12207,7 +12211,7 @@ static int lfsr_file_crystallize_(lfs_t *lfs, lfsr_file_t *file,
// but make sure to include all of the requested
// crystal if explicit, otherwise above loops
// may never terminate
&& (lfs_soff_t)(pos_ - block_pos) >= crystal_size) {
&& (lfs_soff_t)(pos_ - block_pos) >= crystal_min) {
break;
}
@@ -12319,7 +12323,7 @@ static int lfsr_file_crystallize(lfs_t *lfs, lfsr_file_t *file,
// crystallize
int err = lfsr_file_crystallize_(lfs, file,
block_pos, crystal_size,
block_pos, crystal_size, -1,
pos, buffer, size);
if (err) {
return err;