mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-06 02:55:49 +03:00
Kernel+SystemMonitor: Expose amount of per-process clean inode memory
This is memory that's loaded from an inode (file) but not modified in memory, so still identical to what's on disk. This kind of memory can be freed and reloaded transparently from disk if needed.
This commit is contained in:
parent
0d5e0e4cad
commit
c74cde918a
Notes:
sideshowbarker
2024-07-19 10:34:08 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c74cde918a5
@ -61,6 +61,8 @@ String ProcessModel::column_name(int column) const
|
||||
return "Physical";
|
||||
case Column::DirtyPrivate:
|
||||
return "DirtyP";
|
||||
case Column::CleanInode:
|
||||
return "CleanI";
|
||||
case Column::PurgeableVolatile:
|
||||
return "Purg:V";
|
||||
case Column::PurgeableNonvolatile:
|
||||
@ -115,6 +117,8 @@ GModel::ColumnMetadata ProcessModel::column_metadata(int column) const
|
||||
return { 65, TextAlignment::CenterRight };
|
||||
case Column::DirtyPrivate:
|
||||
return { 65, TextAlignment::CenterRight };
|
||||
case Column::CleanInode:
|
||||
return { 65, TextAlignment::CenterRight };
|
||||
case Column::PurgeableVolatile:
|
||||
return { 65, TextAlignment::CenterRight };
|
||||
case Column::PurgeableNonvolatile:
|
||||
@ -189,6 +193,8 @@ GVariant ProcessModel::data(const GModelIndex& index, Role role) const
|
||||
return (int)thread.current_state.amount_resident;
|
||||
case Column::DirtyPrivate:
|
||||
return (int)thread.current_state.amount_dirty_private;
|
||||
case Column::CleanInode:
|
||||
return (int)thread.current_state.amount_clean_inode;
|
||||
case Column::PurgeableVolatile:
|
||||
return (int)thread.current_state.amount_purgeable_volatile;
|
||||
case Column::PurgeableNonvolatile:
|
||||
@ -258,6 +264,8 @@ GVariant ProcessModel::data(const GModelIndex& index, Role role) const
|
||||
return pretty_byte_size(thread.current_state.amount_resident);
|
||||
case Column::DirtyPrivate:
|
||||
return pretty_byte_size(thread.current_state.amount_dirty_private);
|
||||
case Column::CleanInode:
|
||||
return pretty_byte_size(thread.current_state.amount_clean_inode);
|
||||
case Column::PurgeableVolatile:
|
||||
return pretty_byte_size(thread.current_state.amount_purgeable_volatile);
|
||||
case Column::PurgeableNonvolatile:
|
||||
@ -320,6 +328,7 @@ void ProcessModel::update()
|
||||
state.amount_virtual = it.value.amount_virtual;
|
||||
state.amount_resident = it.value.amount_resident;
|
||||
state.amount_dirty_private = it.value.amount_dirty_private;
|
||||
state.amount_clean_inode = it.value.amount_clean_inode;
|
||||
state.amount_purgeable_volatile = it.value.amount_purgeable_volatile;
|
||||
state.amount_purgeable_nonvolatile = it.value.amount_purgeable_nonvolatile;
|
||||
state.icon_id = it.value.icon_id;
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
Virtual,
|
||||
Physical,
|
||||
DirtyPrivate,
|
||||
CleanInode,
|
||||
PurgeableVolatile,
|
||||
PurgeableNonvolatile,
|
||||
Syscalls,
|
||||
@ -74,6 +75,7 @@ private:
|
||||
size_t amount_virtual;
|
||||
size_t amount_resident;
|
||||
size_t amount_dirty_private;
|
||||
size_t amount_clean_inode;
|
||||
size_t amount_purgeable_volatile;
|
||||
size_t amount_purgeable_nonvolatile;
|
||||
unsigned syscall_count;
|
||||
|
@ -754,6 +754,7 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
|
||||
process_object.add("amount_virtual", (u32)process.amount_virtual());
|
||||
process_object.add("amount_resident", (u32)process.amount_resident());
|
||||
process_object.add("amount_dirty_private", (u32)process.amount_dirty_private());
|
||||
process_object.add("amount_clean_inode", (u32)process.amount_clean_inode());
|
||||
process_object.add("amount_shared", (u32)process.amount_shared());
|
||||
process_object.add("amount_purgeable_volatile", (u32)process.amount_purgeable_volatile());
|
||||
process_object.add("amount_purgeable_nonvolatile", (u32)process.amount_purgeable_nonvolatile());
|
||||
|
@ -2504,6 +2504,9 @@ void Process::die()
|
||||
|
||||
size_t Process::amount_dirty_private() const
|
||||
{
|
||||
// FIXME: This gets a bit more complicated for Regions sharing the same underlying VMObject.
|
||||
// The main issue I'm thinking of is when the VMObject has physical pages that none of the Regions are mapping.
|
||||
// That's probably a situation that needs to be looked at in general.
|
||||
size_t amount = 0;
|
||||
for (auto& region : m_regions) {
|
||||
if (!region.is_shared())
|
||||
@ -2512,6 +2515,19 @@ size_t Process::amount_dirty_private() const
|
||||
return amount;
|
||||
}
|
||||
|
||||
size_t Process::amount_clean_inode() const
|
||||
{
|
||||
HashTable<const InodeVMObject*> vmobjects;
|
||||
for (auto& region : m_regions) {
|
||||
if (region.vmobject().is_inode())
|
||||
vmobjects.set(&static_cast<const InodeVMObject&>(region.vmobject()));
|
||||
}
|
||||
size_t amount = 0;
|
||||
for (auto& vmobject : vmobjects)
|
||||
amount += vmobject->amount_clean();
|
||||
return amount;
|
||||
}
|
||||
|
||||
size_t Process::amount_virtual() const
|
||||
{
|
||||
size_t amount = 0;
|
||||
|
@ -272,6 +272,7 @@ public:
|
||||
int number_of_open_file_descriptors() const;
|
||||
int max_open_file_descriptors() const { return m_max_open_file_descriptors; }
|
||||
|
||||
size_t amount_clean_inode() const;
|
||||
size_t amount_dirty_private() const;
|
||||
size_t amount_virtual() const;
|
||||
size_t amount_resident() const;
|
||||
|
@ -36,6 +36,16 @@ InodeVMObject::~InodeVMObject()
|
||||
ASSERT(inode().vmobject() == this);
|
||||
}
|
||||
|
||||
size_t InodeVMObject::amount_clean() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (int i = 0; i < m_dirty_pages.size(); ++i) {
|
||||
if (!m_dirty_pages.get(i) && m_physical_pages[i])
|
||||
++count;
|
||||
}
|
||||
return count * PAGE_SIZE;
|
||||
}
|
||||
|
||||
size_t InodeVMObject::amount_dirty() const
|
||||
{
|
||||
size_t count = 0;
|
||||
|
@ -17,6 +17,7 @@ public:
|
||||
void inode_size_changed(Badge<Inode>, size_t old_size, size_t new_size);
|
||||
|
||||
size_t amount_dirty() const;
|
||||
size_t amount_clean() const;
|
||||
|
||||
private:
|
||||
explicit InodeVMObject(Inode&);
|
||||
|
@ -39,6 +39,7 @@ HashMap<pid_t, CProcessStatistics> CProcessStatisticsReader::get_all()
|
||||
process.amount_resident = process_object.get("amount_resident").to_u32();
|
||||
process.amount_shared = process_object.get("amount_shared").to_u32();
|
||||
process.amount_dirty_private = process_object.get("amount_dirty_private").to_u32();
|
||||
process.amount_clean_inode = process_object.get("amount_clean_inode").to_u32();
|
||||
process.amount_purgeable_volatile = process_object.get("amount_purgeable_volatile").to_u32();
|
||||
process.amount_purgeable_nonvolatile = process_object.get("amount_purgeable_nonvolatile").to_u32();
|
||||
process.icon_id = process_object.get("icon_id").to_int();
|
||||
|
@ -40,6 +40,7 @@ struct CProcessStatistics {
|
||||
size_t amount_resident;
|
||||
size_t amount_shared;
|
||||
size_t amount_dirty_private;
|
||||
size_t amount_clean_inode;
|
||||
size_t amount_purgeable_volatile;
|
||||
size_t amount_purgeable_nonvolatile;
|
||||
int icon_id;
|
||||
|
Loading…
Reference in New Issue
Block a user