[kernel] Pull block_allocator out into separate class

The vm_area_guarded code to keep a list of used/free block addresses
will be useful elsewhere.
This commit is contained in:
Justin C. Miller
2022-09-11 14:12:18 -07:00
parent 1d4c66a9a0
commit 7fd39e91c1
3 changed files with 40 additions and 19 deletions

View File

@@ -0,0 +1,28 @@
#pragma once
/// \file block_allocator.h
/// Definitions and functions for a generic block allocator
#include <stddef.h>
#include <util/vector.h>
class block_allocator
{
public:
inline block_allocator(uintptr_t start, size_t size) :
m_next_block(start), m_block_size(size) {}
inline uintptr_t allocate() {
if (m_free.count() > 0)
return m_free.pop();
else
return __atomic_fetch_add(&m_next_block, m_block_size, __ATOMIC_SEQ_CST);
}
inline void free(uintptr_t p) { m_free.append(p); }
inline uintptr_t end() const { return m_next_block; }
private:
uintptr_t m_next_block;
const size_t m_block_size;
util::vector<uintptr_t> m_free;
};

View File

@@ -143,9 +143,8 @@ vm_area_open::get_page(uintptr_t offset, uintptr_t &phys)
vm_area_guarded::vm_area_guarded(uintptr_t start, size_t buf_pages, size_t size, vm_flags flags) : vm_area_guarded::vm_area_guarded(uintptr_t start, size_t buf_pages, size_t size, vm_flags flags) :
m_start {start}, m_pages {buf_pages + 1}, // Sections are N+1 pages for the leading guard page
m_pages {buf_pages}, m_stacks {start, m_pages*mem::frame_size},
m_next {mem::frame_size},
vm_area_open {size, flags} vm_area_open {size, flags}
{ {
} }
@@ -155,31 +154,26 @@ vm_area_guarded::~vm_area_guarded() {}
uintptr_t uintptr_t
vm_area_guarded::get_section() vm_area_guarded::get_section()
{ {
if (m_cache.count() > 0) { // Account for the leading guard page
return m_cache.pop(); return m_stacks.allocate() + mem::frame_size;
}
uintptr_t addr = m_next;
m_next += (m_pages + 1) * mem::frame_size;
return m_start + addr;
} }
void void
vm_area_guarded::return_section(uintptr_t addr) vm_area_guarded::return_section(uintptr_t addr)
{ {
m_cache.append(addr); // Account for the leading guard page
return m_stacks.free(addr - mem::frame_size);
} }
bool bool
vm_area_guarded::get_page(uintptr_t offset, uintptr_t &phys) vm_area_guarded::get_page(uintptr_t offset, uintptr_t &phys)
{ {
if (offset > m_next) if (offset >= m_stacks.end())
return false; return false;
// make sure this isn't in a guard page. (sections are // make sure this isn't in a guard page. (sections have 1 leading
// m_pages big plus 1 leading guard page, so page 0 is // guard page, so page 0 is invalid)
// invalid) if ((offset >> 12) % m_pages == 0)
if ((offset >> 12) % (m_pages+1) == 0)
return false; return false;
return vm_area_open::get_page(offset, phys); return vm_area_open::get_page(offset, phys);

View File

@@ -9,6 +9,7 @@
#include <util/vector.h> #include <util/vector.h>
#include <util/enum_bitfields.h> #include <util/enum_bitfields.h>
#include "block_allocator.h"
#include "objects/kobject.h" #include "objects/kobject.h"
class page_tree; class page_tree;
@@ -174,10 +175,8 @@ public:
virtual bool get_page(uintptr_t offset, uintptr_t &phys) override; virtual bool get_page(uintptr_t offset, uintptr_t &phys) override;
private: private:
util::vector<uintptr_t> m_cache;
uintptr_t m_start;
size_t m_pages; size_t m_pages;
uintptr_t m_next; block_allocator m_stacks;
}; };
} // namespace obj } // namespace obj