diff --git a/kernel/include/kernel/Memory/MemoryRegion.h b/kernel/include/kernel/Memory/MemoryRegion.h index 42e90c14..32fc282c 100644 --- a/kernel/include/kernel/Memory/MemoryRegion.h +++ b/kernel/include/kernel/Memory/MemoryRegion.h @@ -3,8 +3,7 @@ #include #include #include - -#include +#include namespace Kernel { @@ -42,6 +41,10 @@ namespace Kernel size_t virtual_page_count() const { return BAN::Math::div_round_up(m_size, PAGE_SIZE); } size_t physical_page_count() const { return m_physical_page_count; } + void pin() { m_pinned_count++; } + void unpin() { if (--m_pinned_count == 0) m_pinned_blocker.unblock(); } + void wait_not_pinned() { while (m_pinned_count) m_pinned_blocker.block_with_timeout_ms(100); } + virtual BAN::ErrorOr msync(vaddr_t, size_t, int) = 0; // Returns error if no memory was available @@ -64,6 +67,9 @@ namespace Kernel const PageTable::flags_t m_flags; vaddr_t m_vaddr { 0 }; size_t m_physical_page_count { 0 }; + + BAN::Atomic m_pinned_count { 0 }; + ThreadBlocker m_pinned_blocker; }; } diff --git a/kernel/kernel/Memory/MemoryRegion.cpp b/kernel/kernel/Memory/MemoryRegion.cpp index cb306d88..cb334217 100644 --- a/kernel/kernel/Memory/MemoryRegion.cpp +++ b/kernel/kernel/Memory/MemoryRegion.cpp @@ -13,6 +13,7 @@ namespace Kernel MemoryRegion::~MemoryRegion() { + ASSERT(m_pinned_count == 0); if (m_vaddr) m_page_table.unmap_range(m_vaddr, m_size); } diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 7689704f..69ab21a7 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1806,7 +1806,10 @@ namespace Kernel const vaddr_t region_s = region->vaddr(); const vaddr_t region_e = region->vaddr() + region->size(); if (vaddr <= region_s && region_e <= vaddr + len) + { + region->wait_not_pinned(); m_mapped_regions.remove(i--); + } else if (region->overlaps(vaddr, len)) dwarnln("TODO: partial region munmap"); }