diff options
-rw-r--r-- | Kernel/Process.cpp | 10 | ||||
-rw-r--r-- | Kernel/VM/AnonymousVMObject.h | 6 | ||||
-rw-r--r-- | Kernel/VM/ContiguousVMObject.h | 7 | ||||
-rw-r--r-- | Kernel/VM/InodeVMObject.h | 6 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 17 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.h | 11 | ||||
-rw-r--r-- | Kernel/VM/PurgeableVMObject.h | 6 | ||||
-rw-r--r-- | Kernel/VM/VMObject.h | 10 |
8 files changed, 57 insertions, 16 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index cd46574a95..9e292dc043 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -671,9 +671,8 @@ int Process::sys$purge(int mode) NonnullRefPtrVector<PurgeableVMObject> vmobjects; { InterruptDisabler disabler; - MM.for_each_vmobject([&](auto& vmobject) { - if (vmobject.is_purgeable()) - vmobjects.append(static_cast<PurgeableVMObject&>(vmobject)); + MM.for_each_vmobject_of_type<PurgeableVMObject>([&](auto& vmobject) { + vmobjects.append(vmobject); return IterationDecision::Continue; }); } @@ -685,9 +684,8 @@ int Process::sys$purge(int mode) NonnullRefPtrVector<InodeVMObject> vmobjects; { InterruptDisabler disabler; - MM.for_each_vmobject([&](auto& vmobject) { - if (vmobject.is_inode()) - vmobjects.append(static_cast<InodeVMObject&>(vmobject)); + MM.for_each_vmobject_of_type<InodeVMObject>([&](auto& vmobject) { + vmobjects.append(vmobject); return IterationDecision::Continue; }); } diff --git a/Kernel/VM/AnonymousVMObject.h b/Kernel/VM/AnonymousVMObject.h index 9972bab1a4..12da99df43 100644 --- a/Kernel/VM/AnonymousVMObject.h +++ b/Kernel/VM/AnonymousVMObject.h @@ -56,4 +56,10 @@ private: virtual bool is_anonymous() const override { return true; } }; +template<> +inline bool is<AnonymousVMObject>(const VMObject& vmobject) +{ + return vmobject.is_anonymous(); +} + } diff --git a/Kernel/VM/ContiguousVMObject.h b/Kernel/VM/ContiguousVMObject.h index b25d6dc1c0..58de60c944 100644 --- a/Kernel/VM/ContiguousVMObject.h +++ b/Kernel/VM/ContiguousVMObject.h @@ -50,4 +50,11 @@ private: virtual bool is_contiguous() const override { return true; } }; + +template<> +inline bool is<ContiguousVMObject>(const VMObject& vmobject) +{ + return vmobject.is_contiguous(); +} + } diff --git a/Kernel/VM/InodeVMObject.h b/Kernel/VM/InodeVMObject.h index 5ec9013bac..ca5f0af6e7 100644 --- a/Kernel/VM/InodeVMObject.h +++ b/Kernel/VM/InodeVMObject.h @@ -66,4 +66,10 @@ protected: Bitmap m_dirty_pages; }; +template<> +inline bool is<InodeVMObject>(const VMObject& vmobject) +{ + return vmobject.is_inode(); +} + } diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 7268a652df..aa3f7dccc7 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -441,16 +441,13 @@ RefPtr<PhysicalPage> MemoryManager::allocate_user_physical_page(ShouldZeroFill s klog() << "MM: no user physical regions available (?)"; } - for_each_vmobject([&](auto& vmobject) { - if (vmobject.is_purgeable()) { - auto& purgeable_vmobject = static_cast<PurgeableVMObject&>(vmobject); - int purged_page_count = purgeable_vmobject.purge_with_interrupts_disabled({}); - if (purged_page_count) { - klog() << "MM: Purge saved the day! Purged " << purged_page_count << " pages from PurgeableVMObject{" << &purgeable_vmobject << "}"; - page = find_free_user_physical_page(); - ASSERT(page); - return IterationDecision::Break; - } + for_each_vmobject_of_type<PurgeableVMObject>([&](auto& vmobject) { + int purged_page_count = vmobject.purge_with_interrupts_disabled({}); + if (purged_page_count) { + klog() << "MM: Purge saved the day! Purged " << purged_page_count << " pages from PurgeableVMObject{" << &vmobject << "}"; + page = find_free_user_physical_page(); + ASSERT(page); + return IterationDecision::Break; } return IterationDecision::Continue; }); diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index 322a9facc9..f4293fff35 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -125,6 +125,17 @@ public: } } + template<typename T, typename Callback> + static void for_each_vmobject_of_type(Callback callback) + { + for (auto& vmobject : MM.m_vmobjects) { + if (!is<T>(vmobject)) + continue; + if (callback(static_cast<T&>(vmobject)) == IterationDecision::Break) + break; + } + } + static Region* region_from_vaddr(Process&, VirtualAddress); static const Region* region_from_vaddr(const Process&, VirtualAddress); diff --git a/Kernel/VM/PurgeableVMObject.h b/Kernel/VM/PurgeableVMObject.h index 5e100aa5f0..0b63801284 100644 --- a/Kernel/VM/PurgeableVMObject.h +++ b/Kernel/VM/PurgeableVMObject.h @@ -64,4 +64,10 @@ private: bool m_volatile { false }; }; +template<> +inline bool is<PurgeableVMObject>(const VMObject& vmobject) +{ + return vmobject.is_purgeable(); +} + } diff --git a/Kernel/VM/VMObject.h b/Kernel/VM/VMObject.h index 79ee9dadad..bb0314301c 100644 --- a/Kernel/VM/VMObject.h +++ b/Kernel/VM/VMObject.h @@ -84,4 +84,14 @@ private: VMObject(VMObject&&) = delete; }; +template<typename T> +inline bool is(const VMObject&) { return false; } + +template<typename T> +inline T& to(VMObject& object) +{ + ASSERT(is<typename RemoveConst<T>::Type>(object)); + return static_cast<T&>(object); +} + } |