diff --git a/Kernel/KBuffer.h b/Kernel/KBuffer.h index 9b2249d1a9..1059191842 100644 --- a/Kernel/KBuffer.h +++ b/Kernel/KBuffer.h @@ -1,14 +1,13 @@ /* - * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2018-2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -// KBuffer: Statically sized kernel-only memory buffer. +// KBuffer: Memory buffer backed by a kernel region. // -// A KBuffer is a value-type convenience class that wraps a NonnullRefPtr. // The memory is allocated via the global kernel-only page allocator, rather than via // kmalloc() which is what ByteBuffer/Vector/etc will use. // @@ -17,51 +16,34 @@ // severely limited kmalloc heap. #include -#include #include #include #include -#include namespace Kernel { -class KBufferImpl : public RefCounted { +class [[nodiscard]] KBuffer { public: - static RefPtr try_create_with_size(size_t size, Memory::Region::Access access, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) + static KResultOr> try_create_with_size(size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) { - auto region_or_error = MM.allocate_kernel_region(Memory::page_round_up(size), name, access, strategy); - if (region_or_error.is_error()) - return nullptr; - return adopt_ref_if_nonnull(new (nothrow) KBufferImpl(region_or_error.release_value(), size, strategy)); + auto region = TRY(MM.allocate_kernel_region(Memory::page_round_up(size), name, access, strategy)); + return TRY(adopt_nonnull_own_or_enomem(new (nothrow) KBuffer { size, move(region) })); } - static RefPtr try_create_with_bytes(ReadonlyBytes bytes, Memory::Region::Access access, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) + static KResultOr> try_create_with_bytes(ReadonlyBytes bytes, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) { - auto region_or_error = MM.allocate_kernel_region(Memory::page_round_up(bytes.size()), name, access, strategy); - if (region_or_error.is_error()) - return nullptr; - auto region = region_or_error.release_value(); - memcpy(region->vaddr().as_ptr(), bytes.data(), bytes.size()); - - return adopt_ref_if_nonnull(new (nothrow) KBufferImpl(move(region), bytes.size(), strategy)); - } - - static RefPtr create_with_size(size_t size, Memory::Region::Access access, StringView name, AllocationStrategy strategy = AllocationStrategy::Reserve) - { - return try_create_with_size(size, access, name, strategy); - } - - static RefPtr copy(const void* data, size_t size, Memory::Region::Access access, StringView name) - { - auto buffer = create_with_size(size, access, name, AllocationStrategy::AllocateNow); - if (!buffer) - return {}; - memcpy(buffer->data(), data, size); + auto buffer = TRY(try_create_with_size(bytes.size(), access, name, strategy)); + memcpy(buffer->data(), bytes.data(), bytes.size()); return buffer; } + static KResultOr> try_copy(const void* data, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer") + { + return try_create_with_bytes(ReadonlyBytes { data, size }, access, name); + } + [[nodiscard]] u8* data() { return m_region->vaddr().as_ptr(); } - [[nodiscard]] const u8* data() const { return m_region->vaddr().as_ptr(); } + [[nodiscard]] u8 const* data() const { return m_region->vaddr().as_ptr(); } [[nodiscard]] size_t size() const { return m_size; } [[nodiscard]] size_t capacity() const { return m_region->size(); } @@ -71,62 +53,15 @@ public: m_size = size; } - [[nodiscard]] Memory::Region const& region() const { return *m_region; } - [[nodiscard]] Memory::Region& region() { return *m_region; } - private: - explicit KBufferImpl(NonnullOwnPtr&& region, size_t size, AllocationStrategy strategy) + explicit KBuffer(size_t size, NonnullOwnPtr region) : m_size(size) - , m_allocation_strategy(strategy) , m_region(move(region)) { } size_t m_size { 0 }; - AllocationStrategy m_allocation_strategy { AllocationStrategy::Reserve }; NonnullOwnPtr m_region; }; -class [[nodiscard]] KBuffer { -public: - static KResultOr> try_create_with_size(size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) - { - auto impl = KBufferImpl::try_create_with_size(size, access, name, strategy); - if (!impl) - return ENOMEM; - return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull())); - } - - static KResultOr> try_create_with_bytes(ReadonlyBytes bytes, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) - { - auto impl = KBufferImpl::try_create_with_bytes(bytes, access, name, strategy); - if (!impl) - return ENOMEM; - return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull())); - } - - static KResultOr> try_copy(const void* data, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer") - { - auto impl = KBufferImpl::copy(data, size, access, name); - if (!impl) - return ENOMEM; - return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull())); - } - - [[nodiscard]] u8* data() { return m_impl->data(); } - [[nodiscard]] const u8* data() const { return m_impl->data(); } - [[nodiscard]] size_t size() const { return m_impl->size(); } - [[nodiscard]] size_t capacity() const { return m_impl->capacity(); } - - void set_size(size_t size) { m_impl->set_size(size); } - -private: - explicit KBuffer(NonnullRefPtr impl) - : m_impl(move(impl)) - { - } - - NonnullRefPtr m_impl; -}; - }