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%)
This commit is contained in:
Christopher Haster
2023-12-28 23:09:41 -06:00
parent cd9c1c0c31
commit 8976b6f9ff
+14 -8
View File
@@ -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