diff --git a/modules.yaml b/modules.yaml index fe23e1f..357fb51 100644 --- a/modules.yaml +++ b/modules.yaml @@ -46,7 +46,7 @@ modules: - src/kernel/scheduler.cpp - src/kernel/screen.cpp - src/kernel/serial.cpp - - src/kernel/stack_cache.cpp + - src/kernel/buffer_cache.cpp - src/kernel/symbol_table.cpp - src/kernel/syscall.cpp - src/kernel/syscall.s diff --git a/src/kernel/buffer_cache.cpp b/src/kernel/buffer_cache.cpp new file mode 100644 index 0000000..9951c2b --- /dev/null +++ b/src/kernel/buffer_cache.cpp @@ -0,0 +1,48 @@ +#include "kutil/assert.h" +#include "kutil/vm_space.h" +#include "kernel_memory.h" +#include "page_manager.h" +#include "buffer_cache.h" + +extern kutil::vm_space g_kernel_space; + +using memory::frame_size; +using memory::kernel_stack_pages; +using memory::kernel_buffer_pages; + +static constexpr size_t stack_bytes = kernel_stack_pages * frame_size; +static constexpr size_t buffer_bytes = kernel_buffer_pages * frame_size; + +buffer_cache g_kstack_cache {memory::stacks_start, stack_bytes, memory::kernel_max_stacks}; +buffer_cache g_kbuffer_cache {memory::buffers_start, buffer_bytes, memory::kernel_max_buffers}; + +buffer_cache::buffer_cache(uintptr_t start, size_t size, size_t length) : + m_next(start), m_end(start+length), m_size(size) +{ + kassert((size % frame_size) == 0, "buffer_cache given a non-page-multiple size!"); +} + +uintptr_t +buffer_cache::get_buffer() +{ + uintptr_t addr = 0; + if (m_cache.count() > 0) { + addr = m_cache.pop(); + } else { + addr = m_next; + m_next += m_size; + } + + g_kernel_space.commit(addr, m_size); + return addr; +} + +void +buffer_cache::return_buffer(uintptr_t addr) +{ + void *ptr = reinterpret_cast(addr); + size_t page_count = page_manager::page_count(m_size); + page_manager::get()->unmap_pages(ptr, page_count); + g_kernel_space.unreserve(addr, m_size); + m_cache.append(addr); +} diff --git a/src/kernel/buffer_cache.h b/src/kernel/buffer_cache.h new file mode 100644 index 0000000..01994d4 --- /dev/null +++ b/src/kernel/buffer_cache.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +/// A cache of kernel stack address ranges +class buffer_cache +{ +public: + /// Constructor. + /// \args start Start of virtual memory area to contain buffers + /// \args size Size of individual buffers in bytes + /// \args length Size of virtual memory area in bytes + buffer_cache(uintptr_t start, size_t size, size_t length); + + /// Get an available stack address + uintptr_t get_buffer(); + + /// Return a buffer address to the available pool + void return_buffer(uintptr_t addr); + +private: + kutil::vector m_cache; + uintptr_t m_next; + const uintptr_t m_end; + const size_t m_size; +}; + +extern buffer_cache g_kstack_cache; +extern buffer_cache g_kbuffer_cache; diff --git a/src/kernel/objects/thread.cpp b/src/kernel/objects/thread.cpp index 1cbc0e2..1d1ee46 100644 --- a/src/kernel/objects/thread.cpp +++ b/src/kernel/objects/thread.cpp @@ -3,7 +3,7 @@ #include "objects/thread.h" #include "objects/process.h" #include "scheduler.h" -#include "stack_cache.h" +#include "buffer_cache.h" extern "C" void kernel_to_user_trampoline(); static constexpr j6_signal_t thread_default_signals = 0; @@ -29,7 +29,7 @@ thread::thread(process &parent, uint8_t pri, uintptr_t rsp0) : thread::~thread() { - stack_cache::get().return_stack(m_tcb.kernel_stack); + g_kstack_cache.return_buffer(m_tcb.kernel_stack); } thread * @@ -150,7 +150,7 @@ thread::setup_kernel_stack() constexpr unsigned null_frame_entries = 2; constexpr size_t null_frame_size = null_frame_entries * sizeof(uint64_t); - uintptr_t stack_addr = stack_cache::get().get_stack(); + uintptr_t stack_addr = g_kstack_cache.get_buffer(); uintptr_t stack_end = stack_addr + stack_bytes; uint64_t *null_frame = reinterpret_cast(stack_end - null_frame_size); diff --git a/src/kernel/stack_cache.cpp b/src/kernel/stack_cache.cpp deleted file mode 100644 index becbf4a..0000000 --- a/src/kernel/stack_cache.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "kutil/vm_space.h" -#include "kernel_memory.h" -#include "page_manager.h" -#include "stack_cache.h" - -extern kutil::vm_space g_kernel_space; - -using memory::frame_size; -using memory::kernel_stack_pages; -static constexpr size_t stack_bytes = kernel_stack_pages * frame_size; - -stack_cache stack_cache::s_instance(memory::stacks_start, memory::kernel_max_stacks); - -stack_cache::stack_cache(uintptr_t start, size_t size) : - m_next(start), m_end(start+size) -{ -} - -uintptr_t -stack_cache::get_stack() -{ - uintptr_t stack = 0; - if (m_cache.count() > 0) { - stack = m_cache.pop(); - } else { - stack = m_next; - m_next += stack_bytes; - } - - g_kernel_space.commit(stack, stack_bytes); - return stack; -} - -void -stack_cache::return_stack(uintptr_t addr) -{ - void *ptr = reinterpret_cast(addr); - page_manager::get()->unmap_pages(ptr, kernel_stack_pages); - g_kernel_space.unreserve(addr, stack_bytes); - m_cache.append(addr); -} diff --git a/src/kernel/stack_cache.h b/src/kernel/stack_cache.h deleted file mode 100644 index de12f80..0000000 --- a/src/kernel/stack_cache.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -/// A cache of kernel stack address ranges -class stack_cache -{ -public: - /// Constructor. - /// \args start Start of virtual memory area to contain stacks - /// \args size Size of virtual memory area in bytes - stack_cache(uintptr_t start, size_t size); - - /// Get an available stack address - uintptr_t get_stack(); - - /// Return a stack address to the available pool - void return_stack(uintptr_t addr); - - static stack_cache & get() { return s_instance; } - -private: - kutil::vector m_cache; - uintptr_t m_next; - const uintptr_t m_end; - static stack_cache s_instance; -};