diff --git a/Kernel/DoubleBuffer.cpp b/Kernel/DoubleBuffer.cpp index 512c5064071e18..d4015f12e5e1a0 100644 --- a/Kernel/DoubleBuffer.cpp +++ b/Kernel/DoubleBuffer.cpp @@ -1,32 +1,20 @@ #include -inline void DoubleBuffer::compute_lockfree_metadata() +inline void DoubleBuffer::compute_emptiness() { - InterruptDisabler disabler; - m_empty = m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size == 0; - m_space_for_writing = m_capacity - m_write_buffer->size; -} - -DoubleBuffer::DoubleBuffer(size_t capacity) - : m_write_buffer(&m_buffer1) - , m_read_buffer(&m_buffer2) - , m_storage(KBuffer::create_with_size(capacity * 2)) - , m_capacity(capacity) -{ - m_buffer1.data = m_storage.data(); - m_buffer1.size = 0; - m_buffer2.data = m_storage.data() + capacity; - m_buffer2.size = 0; - m_space_for_writing = capacity; + m_empty = m_read_buffer_index >= m_read_buffer->size() && m_write_buffer->is_empty(); } void DoubleBuffer::flip() { - ASSERT(m_read_buffer_index == m_read_buffer->size); + ASSERT(m_read_buffer_index == m_read_buffer->size()); swap(m_read_buffer, m_write_buffer); - m_write_buffer->size = 0; + if (m_write_buffer->capacity() < 32) + m_write_buffer->clear_with_capacity(); + else + m_write_buffer->clear(); m_read_buffer_index = 0; - compute_lockfree_metadata(); + compute_emptiness(); } ssize_t DoubleBuffer::write(const u8* data, ssize_t size) @@ -34,11 +22,8 @@ ssize_t DoubleBuffer::write(const u8* data, ssize_t size) if (!size) return 0; LOCKER(m_lock); - ASSERT(size <= (ssize_t)space_for_writing()); - u8* write_ptr = m_write_buffer->data + m_write_buffer->size; - m_write_buffer->size += size; - compute_lockfree_metadata(); - memcpy(write_ptr, data, size); + m_write_buffer->append(data, size); + compute_emptiness(); return size; } @@ -47,13 +32,13 @@ ssize_t DoubleBuffer::read(u8* data, ssize_t size) if (!size) return 0; LOCKER(m_lock); - if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0) + if (m_read_buffer_index >= m_read_buffer->size() && !m_write_buffer->is_empty()) flip(); - if (m_read_buffer_index >= m_read_buffer->size) + if (m_read_buffer_index >= m_read_buffer->size()) return 0; - ssize_t nread = min((ssize_t)m_read_buffer->size - (ssize_t)m_read_buffer_index, size); - memcpy(data, m_read_buffer->data + m_read_buffer_index, nread); + ssize_t nread = min((ssize_t)m_read_buffer->size() - m_read_buffer_index, size); + memcpy(data, m_read_buffer->data() + m_read_buffer_index, nread); m_read_buffer_index += nread; - compute_lockfree_metadata(); + compute_emptiness(); return nread; } diff --git a/Kernel/DoubleBuffer.h b/Kernel/DoubleBuffer.h index c2f0f9cab4914f..44094829c9bcfa 100644 --- a/Kernel/DoubleBuffer.h +++ b/Kernel/DoubleBuffer.h @@ -1,38 +1,34 @@ #pragma once #include -#include +#include #include class DoubleBuffer { public: - explicit DoubleBuffer(size_t capacity = 65536); + DoubleBuffer() + : m_write_buffer(&m_buffer1) + , m_read_buffer(&m_buffer2) + { + } ssize_t write(const u8*, ssize_t); ssize_t read(u8*, ssize_t); bool is_empty() const { return m_empty; } - size_t space_for_writing() const { return m_space_for_writing; } + // FIXME: Isn't this racy? What if we get interrupted between getting the buffer pointer and dereferencing it? + ssize_t bytes_in_write_buffer() const { return (ssize_t)m_write_buffer->size(); } private: void flip(); - void compute_lockfree_metadata(); + void compute_emptiness(); - struct InnerBuffer { - u8* data { nullptr }; - size_t size; - }; - - InnerBuffer* m_write_buffer { nullptr }; - InnerBuffer* m_read_buffer { nullptr }; - InnerBuffer m_buffer1; - InnerBuffer m_buffer2; - - KBuffer m_storage; - size_t m_capacity { 0 }; - size_t m_read_buffer_index { 0 }; - size_t m_space_for_writing { 0 }; + Vector* m_write_buffer { nullptr }; + Vector* m_read_buffer { nullptr }; + Vector m_buffer1; + Vector m_buffer2; + ssize_t m_read_buffer_index { 0 }; bool m_empty { true }; - mutable Lock m_lock { "DoubleBuffer" }; + Lock m_lock { "DoubleBuffer" }; }; diff --git a/Kernel/FileSystem/FIFO.cpp b/Kernel/FileSystem/FIFO.cpp index 1e2982f51966fc..6fc77a7b2bf6e6 100644 --- a/Kernel/FileSystem/FIFO.cpp +++ b/Kernel/FileSystem/FIFO.cpp @@ -90,7 +90,7 @@ bool FIFO::can_read(FileDescription&) const bool FIFO::can_write(FileDescription&) const { - return m_buffer.space_for_writing() || !m_readers; + return m_buffer.bytes_in_write_buffer() < 4096 || !m_readers; } ssize_t FIFO::read(FileDescription&, u8* buffer, ssize_t size) diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index e8fe103a95d6c9..c59ab67699410d 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -210,9 +210,9 @@ bool LocalSocket::can_write(FileDescription& description) const { auto role = this->role(description); if (role == Role::Accepted) - return !has_attached_peer(description) || m_for_client.space_for_writing(); + return !has_attached_peer(description) || m_for_client.bytes_in_write_buffer() < 16384; if (role == Role::Connected) - return !has_attached_peer(description) || m_for_server.space_for_writing(); + return !has_attached_peer(description) || m_for_server.bytes_in_write_buffer() < 16384; ASSERT_NOT_REACHED(); } diff --git a/Kernel/TTY/MasterPTY.cpp b/Kernel/TTY/MasterPTY.cpp index 5afeec5355425f..a3caf1b17b2053 100644 --- a/Kernel/TTY/MasterPTY.cpp +++ b/Kernel/TTY/MasterPTY.cpp @@ -81,7 +81,7 @@ bool MasterPTY::can_write_from_slave() const { if (m_closed) return true; - return m_buffer.space_for_writing(); + return m_buffer.bytes_in_write_buffer() < 4096; } void MasterPTY::close()