diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp index ee56865b64..81b8842087 100644 --- a/Kernel/MemoryManager.cpp +++ b/Kernel/MemoryManager.cpp @@ -781,7 +781,7 @@ void MemoryManager::unregister_region(Region& region) m_regions.remove(®ion); } -size_t Region::committed() const +size_t Region::amount_resident() const { size_t bytes = 0; for (size_t i = 0; i < page_count(); ++i) { @@ -791,6 +791,17 @@ size_t Region::committed() const return bytes; } +size_t Region::amount_shared() const +{ + size_t bytes = 0; + for (size_t i = 0; i < page_count(); ++i) { + auto& physical_page = m_vmo->physical_pages()[first_page_index() + i]; + if (physical_page && physical_page->retain_count() > 1) + bytes += PAGE_SIZE; + } + return bytes; +} + PageDirectory::~PageDirectory() { ASSERT_INTERRUPTS_DISABLED(); diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index e546350d3d..c2473efa76 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -162,7 +162,8 @@ public: bool page_in(); int commit(); - size_t committed() const; + size_t amount_resident() const; + size_t amount_shared() const; PageDirectory* page_directory() { return m_page_directory.ptr(); } diff --git a/Kernel/ProcFS.cpp b/Kernel/ProcFS.cpp index 66f18912cf..86d1eb501b 100644 --- a/Kernel/ProcFS.cpp +++ b/Kernel/ProcFS.cpp @@ -27,6 +27,7 @@ enum ProcFileType { FI_Root_mm, FI_Root_mounts, FI_Root_kmalloc, + FI_Root_all, FI_Root_summary, FI_Root_cpuinfo, FI_Root_inodes, @@ -216,7 +217,7 @@ ByteBuffer procfs$pid_vm(InodeIdentifier identifier) region->laddr().get(), region->laddr().offset(region->size() - 1).get(), region->size(), - region->committed(), + region->amount_resident(), region->name().characters()); } return builder.to_byte_buffer(); @@ -480,6 +481,33 @@ ByteBuffer procfs$summary(InodeIdentifier) return builder.to_byte_buffer(); } +ByteBuffer procfs$all(InodeIdentifier) +{ + InterruptDisabler disabler; + auto processes = Process::all_processes(); + StringBuilder builder; + for (auto* process : processes) { + builder.appendf("%u,%u,%u,%u,%u,%u,%s,%u,%u,%u,%s,%s,%u,%u,%u\n", + process->pid(), + process->tty() ? process->tty()->pgid() : 0, + process->pgid(), + process->sid(), + process->uid(), + process->gid(), + to_string(process->state()), + process->ppid(), + process->times_scheduled(), + process->number_of_open_file_descriptors(), + process->tty() ? process->tty()->tty_name().characters() : "notty", + process->name().characters(), + process->amount_virtual(), + process->amount_resident(), + process->amount_shared() + ); + } + return builder.to_byte_buffer(); +} + ByteBuffer procfs$inodes(InodeIdentifier) { extern HashTable& all_inodes(); @@ -970,6 +998,7 @@ ProcFS::ProcFS() m_entries[FI_Root_mm] = { "mm", FI_Root_mm, procfs$mm }; m_entries[FI_Root_mounts] = { "mounts", FI_Root_mounts, procfs$mounts }; m_entries[FI_Root_kmalloc] = { "kmalloc", FI_Root_kmalloc, procfs$kmalloc }; + m_entries[FI_Root_all] = { "all", FI_Root_all, procfs$all }; m_entries[FI_Root_summary] = { "summary", FI_Root_summary, procfs$summary }; m_entries[FI_Root_cpuinfo] = { "cpuinfo", FI_Root_summary, procfs$cpuinfo}; m_entries[FI_Root_inodes] = { "inodes", FI_Root_inodes, procfs$inodes }; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index edc5bb08ca..e1d3d1c46c 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -327,7 +327,7 @@ int Process::do_exec(const String& path, Vector&& arguments, Vectorinode(), descriptor->metadata().size); vmo->set_name(descriptor->absolute_path()); - auto* region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "helper", true, false); + RetainPtr region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "helper", true, false); // FIXME: Should we consider doing on-demand paging here? Is it actually useful? bool success = region->page_in(); @@ -374,6 +374,8 @@ int Process::do_exec(const String& path, Vector&& arguments, Vectorsize(); + } + return amount; +} + +size_t Process::amount_resident() const +{ + // FIXME: This will double count if multiple regions use the same physical page. + size_t amount = 0; + for (auto& region : m_regions) { + amount += region->amount_resident(); + } + return amount; +} + +size_t Process::amount_shared() const +{ + // FIXME: This will double count if multiple regions use the same physical page. + // FIXME: It doesn't work at the moment, since it relies on PhysicalPage retain counts, + // and each PhysicalPage is only retained by its VMObject. This needs to be refactored + // so that every Region contributes +1 retain to each of its PhysicalPages. + size_t amount = 0; + for (auto& region : m_regions) { + amount += region->amount_shared(); + } + return amount; +} diff --git a/Kernel/Process.h b/Kernel/Process.h index 2e524e3618..cd337184cb 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -266,6 +266,10 @@ public: bool has_unmasked_pending_signals() const; void terminate_due_to_signal(byte signal); + size_t amount_virtual() const; + size_t amount_resident() const; + size_t amount_shared() const; + Process* fork(RegisterDump&); int exec(const String& path, Vector&& arguments, Vector&& environment);