Kernel: Rewrite pipes using the new ring buffer
This commit is contained in:
parent
493b5cb9b1
commit
8b8af1a9d9
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <BAN/Array.h>
|
#include <BAN/Array.h>
|
||||||
#include <kernel/FS/Inode.h>
|
#include <kernel/FS/Inode.h>
|
||||||
|
#include <kernel/Memory/ByteRingBuffer.h>
|
||||||
#include <kernel/ThreadBlocker.h>
|
#include <kernel/ThreadBlocker.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
|
|
@ -38,7 +39,7 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
||||||
virtual BAN::ErrorOr<void> fsync_impl() final override { return {}; }
|
virtual BAN::ErrorOr<void> 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 can_write_impl() const override { return true; }
|
||||||
virtual bool has_error_impl() const override { return m_reading_count == 0; }
|
virtual bool has_error_impl() const override { return m_reading_count == 0; }
|
||||||
virtual bool has_hungup_impl() const override { return m_writing_count == 0; }
|
virtual bool has_hungup_impl() const override { return m_writing_count == 0; }
|
||||||
|
|
@ -54,9 +55,7 @@ namespace Kernel
|
||||||
timespec m_ctime {};
|
timespec m_ctime {};
|
||||||
ThreadBlocker m_thread_blocker;
|
ThreadBlocker m_thread_blocker;
|
||||||
|
|
||||||
BAN::Array<uint8_t, PAGE_SIZE> m_buffer;
|
BAN::UniqPtr<ByteRingBuffer> m_buffer;
|
||||||
BAN::Atomic<size_t> m_buffer_size { 0 };
|
|
||||||
size_t m_buffer_tail { 0 };
|
|
||||||
|
|
||||||
BAN::Atomic<uint32_t> m_writing_count { 1 };
|
BAN::Atomic<uint32_t> m_writing_count { 1 };
|
||||||
BAN::Atomic<uint32_t> m_reading_count { 1 };
|
BAN::Atomic<uint32_t> m_reading_count { 1 };
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,16 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static constexpr size_t s_pipe_buffer_size = 0x10000;
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Pipe::create(const Credentials& credentials)
|
BAN::ErrorOr<BAN::RefPtr<Inode>> Pipe::create(const Credentials& credentials)
|
||||||
{
|
{
|
||||||
Pipe* pipe = new Pipe(credentials);
|
auto* pipe_ptr = new Pipe(credentials);
|
||||||
if (pipe == nullptr)
|
if (pipe_ptr == nullptr)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
return BAN::RefPtr<Inode>::adopt(pipe);
|
auto pipe = BAN::RefPtr<Pipe>::adopt(pipe_ptr);
|
||||||
|
pipe->m_buffer = TRY(ByteRingBuffer::create(s_pipe_buffer_size));
|
||||||
|
return BAN::RefPtr<Inode>(pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipe::Pipe(const Credentials& credentials)
|
Pipe::Pipe(const Credentials& credentials)
|
||||||
|
|
@ -69,27 +73,16 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
||||||
{
|
{
|
||||||
while (m_buffer_size == 0)
|
while (m_buffer->empty())
|
||||||
{
|
{
|
||||||
if (m_writing_count == 0)
|
if (m_writing_count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_buffer_size);
|
const size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_buffer->size());
|
||||||
|
memcpy(buffer.data(), m_buffer->get_data().data(), to_copy);
|
||||||
if (m_buffer_tail + to_copy <= m_buffer.size())
|
m_buffer->pop(to_copy);
|
||||||
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;
|
|
||||||
|
|
||||||
m_atime = SystemTimer::get().real_time();
|
m_atime = SystemTimer::get().real_time();
|
||||||
|
|
||||||
|
|
@ -102,7 +95,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
|
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
while (m_buffer_size >= m_buffer.size())
|
while (m_buffer->full())
|
||||||
{
|
{
|
||||||
if (m_reading_count == 0)
|
if (m_reading_count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -112,20 +105,8 @@ namespace Kernel
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
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 to_copy = BAN::Math::min(buffer.size(), m_buffer->free());
|
||||||
const size_t buffer_head = (m_buffer_tail + m_buffer_size) % m_buffer.size();
|
m_buffer->push(buffer.slice(0, to_copy));
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
timespec current_time = SystemTimer::get().real_time();
|
timespec current_time = SystemTimer::get().real_time();
|
||||||
m_mtime = current_time;
|
m_mtime = current_time;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue