diff --git a/Kernel/DoubleBuffer.cpp b/Kernel/DoubleBuffer.cpp index 269a82d544..b549b8a047 100644 --- a/Kernel/DoubleBuffer.cpp +++ b/Kernel/DoubleBuffer.cpp @@ -17,22 +17,36 @@ inline void DoubleBuffer::compute_lockfree_metadata() m_space_for_writing = m_capacity - m_write_buffer->size; } +OwnPtr DoubleBuffer::try_create(size_t capacity) +{ + auto storage = KBuffer::try_create_with_size(capacity * 2, Region::Access::Read | Region::Access::Write, "DoubleBuffer"); + if (!storage) + return {}; + + return adopt_own_if_nonnull(new (nothrow) DoubleBuffer(capacity, storage.release_nonnull())); +} + DoubleBuffer::DoubleBuffer(size_t capacity) + : DoubleBuffer(capacity, KBuffer::try_create_with_size(capacity * 2, Region::Access::Read | Region::Access::Write, "DoubleBuffer").release_nonnull()) +{ +} + +DoubleBuffer::DoubleBuffer(size_t capacity, NonnullOwnPtr storage) : m_write_buffer(&m_buffer1) , m_read_buffer(&m_buffer2) - , m_storage(KBuffer::create_with_size(capacity * 2, Region::Access::Read | Region::Access::Write, "DoubleBuffer")) + , m_storage(move(storage)) , m_capacity(capacity) { - m_buffer1.data = m_storage.data(); + m_buffer1.data = m_storage->data(); m_buffer1.size = 0; - m_buffer2.data = m_storage.data() + capacity; + m_buffer2.data = m_storage->data() + capacity; m_buffer2.size = 0; m_space_for_writing = capacity; } void DoubleBuffer::flip() { - if (m_storage.is_null()) + if (m_storage->is_null()) return; VERIFY(m_read_buffer_index == m_read_buffer->size); swap(m_read_buffer, m_write_buffer); @@ -43,7 +57,7 @@ void DoubleBuffer::flip() KResultOr DoubleBuffer::write(const UserOrKernelBuffer& data, size_t size) { - if (!size || m_storage.is_null()) + if (!size || m_storage->is_null()) return 0; MutexLocker locker(m_lock); size_t bytes_to_write = min(size, m_space_for_writing); @@ -59,7 +73,7 @@ KResultOr DoubleBuffer::write(const UserOrKernelBuffer& data, size_t siz KResultOr DoubleBuffer::read(UserOrKernelBuffer& data, size_t size) { - if (!size || m_storage.is_null()) + if (!size || m_storage->is_null()) return 0; MutexLocker locker(m_lock); if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0) @@ -78,7 +92,7 @@ KResultOr DoubleBuffer::read(UserOrKernelBuffer& data, size_t size) KResultOr DoubleBuffer::peek(UserOrKernelBuffer& data, size_t size) { - if (!size || m_storage.is_null()) + if (!size || m_storage->is_null()) return 0; MutexLocker locker(m_lock); if (m_read_buffer_index >= m_read_buffer->size && m_write_buffer->size != 0) { diff --git a/Kernel/DoubleBuffer.h b/Kernel/DoubleBuffer.h index c99ef5da40..f130bb592d 100644 --- a/Kernel/DoubleBuffer.h +++ b/Kernel/DoubleBuffer.h @@ -16,8 +16,8 @@ namespace Kernel { class DoubleBuffer { public: + [[nodiscard]] static OwnPtr try_create(size_t capacity = 65536); explicit DoubleBuffer(size_t capacity = 65536); - [[nodiscard]] KResultOr write(const UserOrKernelBuffer&, size_t); [[nodiscard]] KResultOr write(const u8* data, size_t size) { @@ -47,6 +47,7 @@ public: } private: + explicit DoubleBuffer(size_t capacity, NonnullOwnPtr storage); void flip(); void compute_lockfree_metadata(); @@ -60,7 +61,7 @@ private: InnerBuffer m_buffer1; InnerBuffer m_buffer2; - KBuffer m_storage; + NonnullOwnPtr m_storage; Function m_unblock_callback; size_t m_capacity { 0 }; size_t m_read_buffer_index { 0 };