mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:07:44 +00:00
Kernel: Use RAII to manage committed physical pages
We had issues with committed physical pages getting miscounted in some situations, and instead of figuring out what was going wrong and making sure all the commits had matching uncommits, this patch makes the problem go away by adding an RAII class to manage this instead. :^) MemoryManager::commit_user_physical_pages() now returns an (optional) CommittedPhysicalPageSet. You can then allocate pages from the page set by calling take_one() on it. Any unallocated pages are uncommitted upon destruction of the page set.
This commit is contained in:
parent
ec49213f7b
commit
fa627c1eb2
4 changed files with 121 additions and 93 deletions
|
@ -102,6 +102,37 @@ struct MemoryManagerData {
|
|||
|
||||
extern RecursiveSpinLock s_mm_lock;
|
||||
|
||||
// This class represents a set of committed physical pages.
|
||||
// When you ask MemoryManager to commit pages for you, you get one of these in return.
|
||||
// You can allocate pages from it via `take_one()`
|
||||
// It will uncommit any (unallocated) remaining pages when destroyed.
|
||||
class CommittedPhysicalPageSet {
|
||||
AK_MAKE_NONCOPYABLE(CommittedPhysicalPageSet);
|
||||
|
||||
public:
|
||||
CommittedPhysicalPageSet(Badge<MemoryManager>, size_t page_count)
|
||||
: m_page_count(page_count)
|
||||
{
|
||||
}
|
||||
|
||||
CommittedPhysicalPageSet(CommittedPhysicalPageSet&& other)
|
||||
: m_page_count(exchange(other.m_page_count, 0))
|
||||
{
|
||||
}
|
||||
|
||||
~CommittedPhysicalPageSet();
|
||||
|
||||
bool is_empty() const { return m_page_count == 0; }
|
||||
size_t page_count() const { return m_page_count; }
|
||||
|
||||
[[nodiscard]] NonnullRefPtr<PhysicalPage> take_one();
|
||||
|
||||
void operator=(CommittedPhysicalPageSet&&) = delete;
|
||||
|
||||
private:
|
||||
size_t m_page_count { 0 };
|
||||
};
|
||||
|
||||
class MemoryManager {
|
||||
AK_MAKE_ETERNAL
|
||||
friend class PageDirectory;
|
||||
|
@ -139,8 +170,9 @@ public:
|
|||
Yes
|
||||
};
|
||||
|
||||
bool commit_user_physical_pages(size_t);
|
||||
void uncommit_user_physical_pages(size_t);
|
||||
Optional<CommittedPhysicalPageSet> commit_user_physical_pages(size_t page_count);
|
||||
void uncommit_user_physical_pages(Badge<CommittedPhysicalPageSet>, size_t page_count);
|
||||
|
||||
NonnullRefPtr<PhysicalPage> allocate_committed_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes);
|
||||
RefPtr<PhysicalPage> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr);
|
||||
RefPtr<PhysicalPage> allocate_supervisor_physical_page();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue