From 50712a595af22c8163259bd15bed3e1a35f2b96c Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 20 Feb 2024 01:14:44 -0600 Subject: [PATCH] Added lfsr_bd_set, mainly for more efficient bd zeroing For some definition of efficient. Like lfsr_bd_cmp/cpy, this is intended to mirror memcmp/cpy/set/etc, though it might get a bit confusing with lfs_set/setattr/etc meaning something a bit different in the codebase... You may notice this reintroduces the small hardcoded buffers we just put in the effort to remove. Unfortunately the rcache access, lfsr_bd_readnext, is really only useful for, well, reading, and lfsr_bd_set is a prog util. Implementing cache-access for progs would require as just as much effort/cost as for reads, but gets a bit messy with calculating checksums, and has less of a use case. We really only need this to fill holes when compacting file data blocks. So, at least for now, I don't think prog cache-access is worth it. Though this can always be tweaked in the future. Code changes: code stack before: 33744 2872 after: 33796 (+0.2%) 2880 (+0.3%) --- lfs.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/lfs.c b/lfs.c index 3492364a..039abf3f 100644 --- a/lfs.c +++ b/lfs.c @@ -525,6 +525,30 @@ static int lfsr_bd_cpy(lfs_t *lfs, return 0; } +static int lfsr_bd_set(lfs_t *lfs, lfs_block_t block, lfs_size_t off, + uint8_t c, lfs_size_t size, + uint32_t *cksum_, uint32_t *flcksum_) { + // just use a small hardcoded buffer + // + // this function is quite a bit more niche than the read-related utils + uint8_t buf[4]; + memset(buf, c, sizeof(buf)); + + while (size > 0) { + lfs_size_t d = lfs_min(size, sizeof(buf)); + int err = lfsr_bd_prog(lfs, block, off, buf, d, + cksum_, flcksum_); + if (err) { + return err; + } + + off += d; + size -= d; + } + + return 0; +} + /// Small type-level utilities /// @@ -10534,16 +10558,12 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file, } // found a hole? fill with zeros - // TODO do something better than byte-level progs here - for (lfs_size_t i = 0; i < (lfs_size_t)d; i++) { - err = lfsr_bd_prog(lfs, bptr.data.u.disk.block, - bptr.cksize + i, - &(uint8_t){0}, 1, - NULL, &bptr.cksum); - if (err) { - LFS_ASSERT(err != LFS_ERR_RANGE); - return err; - } + err = lfsr_bd_set(lfs, bptr.data.u.disk.block, bptr.cksize, + 0, d, + NULL, &bptr.cksum); + if (err) { + LFS_ASSERT(err != LFS_ERR_RANGE); + return err; } pos_ += d;