瀏覽代碼

Kernel: Add a /proc/all process table dump.

This will be useful for implementing some process-related utilities.
Andreas Kling 6 年之前
父節點
當前提交
b51031bb54
共有 5 個文件被更改,包括 83 次插入4 次删除
  1. 12 1
      Kernel/MemoryManager.cpp
  2. 2 1
      Kernel/MemoryManager.h
  3. 30 1
      Kernel/ProcFS.cpp
  4. 35 1
      Kernel/Process.cpp
  5. 4 0
      Kernel/Process.h

+ 12 - 1
Kernel/MemoryManager.cpp

@@ -781,7 +781,7 @@ void MemoryManager::unregister_region(Region& region)
     m_regions.remove(&region);
 }
 
-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();

+ 2 - 1
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(); }
 

+ 30 - 1
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<Inode*>& 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 };

+ 35 - 1
Kernel/Process.cpp

@@ -327,7 +327,7 @@ int Process::do_exec(const String& path, Vector<String>&& arguments, Vector<Stri
 
     auto vmo = VMObject::create_file_backed(descriptor->inode(), 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> 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<String>&& arguments, Vector<Stri
         }
     }
 
+    m_regions.append(move(region));
+
     m_signal_stack_kernel_region = nullptr;
     m_signal_stack_user_region = nullptr;
     m_display_framebuffer_region = nullptr;
@@ -2170,3 +2172,35 @@ void Process::die()
     m_fds.clear();
     destroy_all_windows();
 }
+
+size_t Process::amount_virtual() const
+{
+    size_t amount = 0;
+    for (auto& region : m_regions) {
+        amount += region->size();
+    }
+    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;
+}

+ 4 - 0
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<String>&& arguments, Vector<String>&& environment);