mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 20:17:41 +00:00
Kernel: Put all VMObjects in an InlineLinkedList instead of a HashTable
Using a HashTable to track "all instances of Foo" is only useful if we actually need to look up entries by some kind of index. And since they are HashTable (not HashMap), the pointer *is* the index. Since we have the pointer, we can just use it directly. Duh. This increase sizeof(VMObject) by two pointers, but removes a global table that had an entry for every VMObject, where the cost was higher. It also avoids all the general hash tabling business when creating or destroying VMObjects. Generally we should do more of this. :^)
This commit is contained in:
parent
fffd3a67ad
commit
a96d76fd90
4 changed files with 32 additions and 14 deletions
|
@ -399,17 +399,19 @@ Optional<KBuffer> procfs$self(InodeIdentifier)
|
||||||
|
|
||||||
Optional<KBuffer> procfs$mm(InodeIdentifier)
|
Optional<KBuffer> procfs$mm(InodeIdentifier)
|
||||||
{
|
{
|
||||||
// FIXME: Implement
|
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
KBufferBuilder builder;
|
KBufferBuilder builder;
|
||||||
for (auto* vmo : MM.m_vmos) {
|
u32 vmobject_count = 0;
|
||||||
builder.appendf("VMO: %p %s(%u): p:%4u\n",
|
MemoryManager::for_each_vmobject([&](auto& vmobject) {
|
||||||
vmo,
|
++vmobject_count;
|
||||||
vmo->is_anonymous() ? "anon" : "file",
|
builder.appendf("VMObject: %p %s(%u): p:%4u\n",
|
||||||
vmo->ref_count(),
|
&vmobject,
|
||||||
vmo->page_count());
|
vmobject.is_anonymous() ? "anon" : "file",
|
||||||
}
|
vmobject.ref_count(),
|
||||||
builder.appendf("VMO count: %u\n", MM.m_vmos.size());
|
vmobject.page_count());
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
builder.appendf("VMO count: %u\n", vmobject_count);
|
||||||
builder.appendf("Free physical pages: %u\n", MM.user_physical_pages() - MM.user_physical_pages_used());
|
builder.appendf("Free physical pages: %u\n", MM.user_physical_pages() - MM.user_physical_pages_used());
|
||||||
builder.appendf("Free supervisor physical pages: %u\n", MM.super_physical_pages() - MM.super_physical_pages_used());
|
builder.appendf("Free supervisor physical pages: %u\n", MM.super_physical_pages() - MM.super_physical_pages_used());
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -753,13 +753,13 @@ bool MemoryManager::validate_user_write(const Process& process, VirtualAddress v
|
||||||
void MemoryManager::register_vmo(VMObject& vmo)
|
void MemoryManager::register_vmo(VMObject& vmo)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
m_vmos.set(&vmo);
|
m_vmobjects.append(&vmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::unregister_vmo(VMObject& vmo)
|
void MemoryManager::unregister_vmo(VMObject& vmo)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
m_vmos.remove(&vmo);
|
m_vmobjects.remove(&vmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::register_region(Region& region)
|
void MemoryManager::register_region(Region& region)
|
||||||
|
|
|
@ -80,6 +80,15 @@ public:
|
||||||
unsigned super_physical_pages() const { return m_super_physical_pages; }
|
unsigned super_physical_pages() const { return m_super_physical_pages; }
|
||||||
unsigned super_physical_pages_used() const { return m_super_physical_pages_used; }
|
unsigned super_physical_pages_used() const { return m_super_physical_pages_used; }
|
||||||
|
|
||||||
|
template<typename Callback>
|
||||||
|
static void for_each_vmobject(Callback callback)
|
||||||
|
{
|
||||||
|
for (auto* vmobject = MM.m_vmobjects.head(); vmobject; vmobject = vmobject->next()) {
|
||||||
|
if (callback(*vmobject) == IterationDecision::Break)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryManager();
|
MemoryManager();
|
||||||
~MemoryManager();
|
~MemoryManager();
|
||||||
|
@ -134,10 +143,11 @@ private:
|
||||||
NonnullRefPtrVector<PhysicalRegion> m_user_physical_regions;
|
NonnullRefPtrVector<PhysicalRegion> m_user_physical_regions;
|
||||||
NonnullRefPtrVector<PhysicalRegion> m_super_physical_regions;
|
NonnullRefPtrVector<PhysicalRegion> m_super_physical_regions;
|
||||||
|
|
||||||
HashTable<VMObject*> m_vmos;
|
|
||||||
HashTable<Region*> m_user_regions;
|
HashTable<Region*> m_user_regions;
|
||||||
HashTable<Region*> m_kernel_regions;
|
HashTable<Region*> m_kernel_regions;
|
||||||
|
|
||||||
|
InlineLinkedList<VMObject> m_vmobjects;
|
||||||
|
|
||||||
bool m_quickmap_in_use { false };
|
bool m_quickmap_in_use { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/FixedArray.h>
|
||||||
|
#include <AK/InlineLinkedList.h>
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <AK/FixedArray.h>
|
|
||||||
#include <AK/Weakable.h>
|
#include <AK/Weakable.h>
|
||||||
#include <Kernel/Lock.h>
|
#include <Kernel/Lock.h>
|
||||||
|
|
||||||
|
@ -10,7 +11,8 @@ class Inode;
|
||||||
class PhysicalPage;
|
class PhysicalPage;
|
||||||
|
|
||||||
class VMObject : public RefCounted<VMObject>
|
class VMObject : public RefCounted<VMObject>
|
||||||
, public Weakable<VMObject> {
|
, public Weakable<VMObject>
|
||||||
|
, public InlineLinkedListNode<VMObject> {
|
||||||
friend class MemoryManager;
|
friend class MemoryManager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -27,6 +29,10 @@ public:
|
||||||
|
|
||||||
size_t size() const { return m_physical_pages.size() * PAGE_SIZE; }
|
size_t size() const { return m_physical_pages.size() * PAGE_SIZE; }
|
||||||
|
|
||||||
|
// For InlineLinkedListNode
|
||||||
|
VMObject* m_next { nullptr };
|
||||||
|
VMObject* m_prev { nullptr };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit VMObject(size_t);
|
explicit VMObject(size_t);
|
||||||
explicit VMObject(const VMObject&);
|
explicit VMObject(const VMObject&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue