From 9d6a94aa070343cc8bbb3177a23f66ccdc89132e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 23 May 2025 11:54:54 -0500 Subject: [PATCH] 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... --- lfs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lfs.c b/lfs.c index fde43f6b..6e2a04b3 100644 --- a/lfs.c +++ b/lfs.c @@ -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;