Serenity Operating System
1/*
2 * Copyright (c) 2021, Sahan Fernando <sahan.h.fernando@gmail.com>.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <Kernel/PhysicalAddress.h>
10#include <Kernel/UserOrKernelBuffer.h>
11
12namespace Kernel::Memory {
13
14class RingBuffer {
15public:
16 static ErrorOr<NonnullOwnPtr<RingBuffer>> try_create(StringView region_name, size_t capacity);
17
18 bool has_space() const { return m_num_used_bytes < m_capacity_in_bytes; }
19 bool copy_data_in(UserOrKernelBuffer const& buffer, size_t offset, size_t length, PhysicalAddress& start_of_copied_data, size_t& bytes_copied);
20 ErrorOr<size_t> copy_data_out(size_t size, UserOrKernelBuffer& buffer) const;
21 ErrorOr<PhysicalAddress> reserve_space(size_t size);
22 void reclaim_space(PhysicalAddress chunk_start, size_t chunk_size);
23 PhysicalAddress start_of_used() const;
24
25 Spinlock<LockRank::None>& lock() { return m_lock; }
26 size_t used_bytes() const { return m_num_used_bytes; }
27 PhysicalAddress start_of_region() const { return m_region->physical_page(0)->paddr(); }
28 VirtualAddress vaddr() const { return m_region->vaddr(); }
29 size_t bytes_till_end() const { return (m_capacity_in_bytes - ((m_start_of_used + m_num_used_bytes) % m_capacity_in_bytes)) % m_capacity_in_bytes; };
30
31private:
32 RingBuffer(NonnullOwnPtr<Memory::Region> region, size_t capacity);
33
34 NonnullOwnPtr<Memory::Region> m_region;
35 Spinlock<LockRank::None> m_lock {};
36 size_t m_start_of_used {};
37 size_t m_num_used_bytes {};
38 size_t m_capacity_in_bytes {};
39};
40
41}