diff options
author | Andreas Kling <kling@serenityos.org> | 2020-01-19 13:58:16 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-01-19 14:01:32 +0100 |
commit | 167b57a6b7b9f63a5f17e7a958269921cc692480 (patch) | |
tree | a27993684285db206b7287bd681fcf0d021ddd4b | |
parent | 1d02ac35fc1d9ff98603db27016d5bfa0af1e1fc (diff) | |
download | serenity-167b57a6b7b9f63a5f17e7a958269921cc692480.zip |
TmpFS: Grow the underlying inode buffer with 2x factor when written to
Before this, we would end up in memcpy() churn hell when a program was
doing repeated write() calls to a file in /tmp.
An even better solution will be to only grow the VM allocation of the
underlying buffer and keep using the same physical pages. This would
eliminate all the memcpy() work.
I've benchmarked this using g++ to compile Kernel/Process.cpp.
With these changes, compilation goes from ~35 sec to ~31 sec. :^)
-rw-r--r-- | Kernel/FileSystem/TmpFS.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp index 719073bdeb..eb7e3ce545 100644 --- a/Kernel/FileSystem/TmpFS.cpp +++ b/Kernel/FileSystem/TmpFS.cpp @@ -208,7 +208,15 @@ ssize_t TmpFSInode::write_bytes(off_t offset, ssize_t size, const u8* buffer, Fi if (m_content.has_value() && m_content.value().capacity() >= (size_t)new_size) { m_content.value().set_size(new_size); } else { - auto tmp = KBuffer::create_with_size(new_size); + // Grow the content buffer 2x the new sizeto accomodate repeating write() calls. + // Note that we're not actually committing physical memory to the buffer + // until it's needed. We only grow VM here. + + // FIXME: Fix this so that no memcpy() is necessary, and we can just grow the + // KBuffer and it will add physical pages as needed while keeping the + // existing ones. + auto tmp = KBuffer::create_with_size(new_size * 2); + tmp.set_size(new_size); if (m_content.has_value()) memcpy(tmp.data(), m_content.value().data(), old_size); m_content = move(tmp); |