[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:
28
src/kernel/block_allocator.h
Normal file
28
src/kernel/block_allocator.h
Normal 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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user