From 8976b6f9ffb0ac7a395f8dda1a9b67226fec944e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 28 Dec 2023 23:09:41 -0600 Subject: [PATCH] Changed bypassing writes to update rdonly buffers Before, rdonly buffers were dropped, requiring a re-read for files open RDWR. Now the buffer is updated with whatever data overlaps. This doesn't add _that_ much code cost, and may be beneficial for certain rd/wr patterns in different parts of a file (we don't drop buffers at all in bypassing writes). Though it may be better to open two separate file handles in this use case... We will need this logic anyways for updating multiple in-sync opened file handles. And maybe this logic can be deduplicated then. code stack before: 32848 2944 after 32908 (+0.2%) 2944 (+0.0%) --- lfs.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lfs.c b/lfs.c index 18160865..64631d09 100644 --- a/lfs.c +++ b/lfs.c @@ -10478,19 +10478,27 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file, // strictly necessary, but enforces a more intuitive write order // and avoids weird cases with low-level write heuristics // - // oh, and also avoids issues with out-of-date buffers - // if (!unflushed_ && size >= lfs->cfg->cache_size) { - // clear buffer to avoid out-of-date data - buffer_pos_ = 0; - buffer_size_ = 0; - err = lfsr_ftree_flush(lfs, &file->mdir, &ftree_, pos_, buffer_, size); if (err) { goto failed; } + // update our buffer if we overlap + // + // but do this after writing so we can't fail + if (pos_ < buffer_pos_ + buffer_size_ + && pos_ + size > buffer_pos_) { + memcpy(&file->buffer[pos_ - lfs_min32(buffer_pos_, pos_)], + &buffer_[buffer_pos_ - lfs_min32(pos_, buffer_pos_)], + lfs_min32( + buffer_size_ - ( + pos_ - lfs_min32(buffer_pos_, pos_)), + size - ( + buffer_pos_ - lfs_min32(pos_, buffer_pos_)))); + } + pos_ += size; buffer_ += size; size -= size; @@ -10539,8 +10547,6 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file, goto failed; } unflushed_ = false; - buffer_pos_ = 0; - buffer_size_ = 0; } // mark as unflushed and unsynced, update file, and return amount written