Changed bypassing writes to update buffer with write tail

While I'm happy to have figured out the previous range update logic, it
is quite complicated, and that translates to code cost. Updating the
buffer with the write tail is 1. simpler, and 2. keeps the buffer
updated with the most recent relevant data.

Relying on the previous bypassing/buffer strategy would have been error
prone anyways. The optimization could fall apart the moment you
_increase_ the buffer size, and it doesn't extend well to multiple open
file handles.

The problem with multiple file handles is we don't know what range of
bytes have been affected when we broadcast a sync. So we just overwrite
all other open file buffers.

Fortunately, LFS_O_DESYNC provides an interesting way to avoid this, and
optimize in-file readd->writes.

Code changes, not really that much in the grand scheme of things. For
comparison I included the code cost for unconditionally clearing the
buffer during bypassing writes:

                      code          stack
  update overlap:    33356           3072
  clear buffer:      33292 (-0.2%)   3072 (+0.0%)
  overwrite buffer:  33316 (-0.1%)   3072 (+0.0%)
This commit is contained in:
Christopher Haster
2024-01-04 01:19:23 -06:00
parent 637784d109
commit 3d7ea5b4d4
+8 -12
View File
@@ -10612,19 +10612,15 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
goto failed;
}
// update our buffer if we overlap
// after success, fill our buffer with the tail of our write
//
// 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_))));
}
// note we need to clear the buffer anyways to avoid any
// out-of-date data
memcpy(file->buffer,
&buffer_[size - lfs->cfg->cache_size],
lfs->cfg->cache_size);
buffer_pos_ = pos_ + size - lfs->cfg->cache_size;
buffer_size_ = lfs->cfg->cache_size;
pos_ += size;
buffer_ += size;