From 8b8af1a9d93353a0776f4a4f891eef8526a1e160 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 28 Feb 2026 14:20:52 +0200 Subject: [PATCH] Kernel: Rewrite pipes using the new ring buffer --- kernel/include/kernel/FS/Pipe.h | 7 +++-- kernel/kernel/FS/Pipe.cpp | 47 ++++++++++----------------------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/kernel/include/kernel/FS/Pipe.h b/kernel/include/kernel/FS/Pipe.h index 82f497dd..a4ad4b1b 100644 --- a/kernel/include/kernel/FS/Pipe.h +++ b/kernel/include/kernel/FS/Pipe.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace Kernel @@ -38,7 +39,7 @@ namespace Kernel virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan) override; virtual BAN::ErrorOr fsync_impl() final override { return {}; } - virtual bool can_read_impl() const override { return m_buffer_size > 0; } + virtual bool can_read_impl() const override { return !m_buffer->empty(); } virtual bool can_write_impl() const override { return true; } virtual bool has_error_impl() const override { return m_reading_count == 0; } virtual bool has_hungup_impl() const override { return m_writing_count == 0; } @@ -54,9 +55,7 @@ namespace Kernel timespec m_ctime {}; ThreadBlocker m_thread_blocker; - BAN::Array m_buffer; - BAN::Atomic m_buffer_size { 0 }; - size_t m_buffer_tail { 0 }; + BAN::UniqPtr m_buffer; BAN::Atomic m_writing_count { 1 }; BAN::Atomic m_reading_count { 1 }; diff --git a/kernel/kernel/FS/Pipe.cpp b/kernel/kernel/FS/Pipe.cpp index c3823b7e..52a142be 100644 --- a/kernel/kernel/FS/Pipe.cpp +++ b/kernel/kernel/FS/Pipe.cpp @@ -9,12 +9,16 @@ namespace Kernel { + static constexpr size_t s_pipe_buffer_size = 0x10000; + BAN::ErrorOr> Pipe::create(const Credentials& credentials) { - Pipe* pipe = new Pipe(credentials); - if (pipe == nullptr) + auto* pipe_ptr = new Pipe(credentials); + if (pipe_ptr == nullptr) return BAN::Error::from_errno(ENOMEM); - return BAN::RefPtr::adopt(pipe); + auto pipe = BAN::RefPtr::adopt(pipe_ptr); + pipe->m_buffer = TRY(ByteRingBuffer::create(s_pipe_buffer_size)); + return BAN::RefPtr(pipe); } Pipe::Pipe(const Credentials& credentials) @@ -69,27 +73,16 @@ namespace Kernel BAN::ErrorOr Pipe::read_impl(off_t, BAN::ByteSpan buffer) { - while (m_buffer_size == 0) + while (m_buffer->empty()) { if (m_writing_count == 0) return 0; TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex)); } - const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer_size); - - if (m_buffer_tail + to_copy <= m_buffer.size()) - memcpy(buffer.data(), m_buffer.data() + m_buffer_tail, to_copy); - else - { - const size_t before_wrap = m_buffer.size() - m_buffer_tail; - const size_t after_wrap = to_copy - before_wrap; - memcpy(buffer.data(), m_buffer.data() + m_buffer_tail, before_wrap); - memcpy(buffer.data() + before_wrap, m_buffer.data(), after_wrap); - } - - m_buffer_tail = (m_buffer_tail + to_copy) % m_buffer.size(); - m_buffer_size -= to_copy; + const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer->size()); + memcpy(buffer.data(), m_buffer->get_data().data(), to_copy); + m_buffer->pop(to_copy); m_atime = SystemTimer::get().real_time(); @@ -102,7 +95,7 @@ namespace Kernel BAN::ErrorOr Pipe::write_impl(off_t, BAN::ConstByteSpan buffer) { - while (m_buffer_size >= m_buffer.size()) + while (m_buffer->full()) { if (m_reading_count == 0) { @@ -112,20 +105,8 @@ namespace Kernel TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex)); } - const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer.size() - m_buffer_size); - const size_t buffer_head = (m_buffer_tail + m_buffer_size) % m_buffer.size(); - - if (buffer_head + to_copy <= m_buffer.size()) - memcpy(m_buffer.data() + buffer_head, buffer.data(), to_copy); - else - { - const size_t before_wrap = m_buffer.size() - buffer_head; - const size_t after_wrap = to_copy - before_wrap; - memcpy(m_buffer.data() + buffer_head, buffer.data(), before_wrap); - memcpy(m_buffer.data(), buffer.data() + before_wrap, after_wrap); - } - - m_buffer_size += to_copy; + const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer->free()); + m_buffer->push(buffer.slice(0, to_copy)); timespec current_time = SystemTimer::get().real_time(); m_mtime = current_time;