Kernel: Make syscall counters and page fault counters per-thread

Now that we show individual threads in SystemMonitor and "top",
it's also very nice to have individual counters for the threads. :^)
This commit is contained in:
Andreas Kling 2019-11-26 21:35:24 +01:00
parent 712ae73581
commit 5b8cf2ee23
Notes: sideshowbarker 2024-07-19 11:03:10 +09:00
9 changed files with 38 additions and 38 deletions

View file

@ -237,10 +237,10 @@ void ProcessModel::update()
ThreadState state;
state.pid = it.value.pid;
state.user = it.value.username;
state.syscall_count = it.value.syscall_count;
state.inode_faults = it.value.inode_faults;
state.zero_faults = it.value.zero_faults;
state.cow_faults = it.value.cow_faults;
state.syscall_count = thread.syscall_count;
state.inode_faults = thread.inode_faults;
state.zero_faults = thread.zero_faults;
state.cow_faults = thread.cow_faults;
state.name = it.value.name;
state.amount_virtual = it.value.amount_virtual;
state.amount_resident = it.value.amount_resident;

View file

@ -689,10 +689,6 @@ 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_shared", (u32)process.amount_shared());
process_object.add("syscall_count", process.syscall_count());
process_object.add("inode_faults", process.inode_faults());
process_object.add("zero_faults", process.zero_faults());
process_object.add("cow_faults", process.cow_faults());
process_object.add("icon_id", process.icon_id());
auto thread_array = process_object.add_array("threads");
process.for_each_thread([&](const Thread& thread) {
@ -702,6 +698,10 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
thread_object.add("ticks", thread.ticks());
thread_object.add("state", thread.state_string());
thread_object.add("priority", to_string(thread.priority()));
thread_object.add("syscall_count", thread.syscall_count());
thread_object.add("inode_faults", thread.inode_faults());
thread_object.add("zero_faults", thread.zero_faults());
thread_object.add("cow_faults", thread.cow_faults());
return IterationDecision::Continue;
});
};

View file

@ -286,15 +286,6 @@ public:
Lock& big_lock() { return m_big_lock; }
unsigned syscall_count() const { return m_syscall_count; }
void did_syscall() { ++m_syscall_count; }
unsigned inode_faults() const { return m_inode_faults; }
void did_inode_fault() { ++m_inode_faults; }
unsigned zero_faults() const { return m_zero_faults; }
void did_zero_fault() { ++m_zero_faults; }
unsigned cow_faults() const { return m_cow_faults; }
void did_cow_fault() { ++m_cow_faults; }
const ELFLoader* elf_loader() const { return m_elf_loader.ptr(); }
int icon_id() const { return m_icon_id; }
@ -373,11 +364,6 @@ private:
int m_next_tid { 0 };
unsigned m_syscall_count { 0 };
unsigned m_inode_faults { 0 };
unsigned m_zero_faults { 0 };
unsigned m_cow_faults { 0 };
RefPtr<ProcessTracer> m_tracer;
OwnPtr<ELFLoader> m_elf_loader;

View file

@ -60,7 +60,7 @@ int handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3)
{
ASSERT_INTERRUPTS_ENABLED();
auto& process = current->process();
process.did_syscall();
current->did_syscall();
if (function == SC_exit || function == SC_exit_thread) {
// These syscalls need special handling since they never return to the caller.

View file

@ -331,6 +331,15 @@ public:
void make_thread_specific_region(Badge<Process>);
unsigned syscall_count() const { return m_syscall_count; }
void did_syscall() { ++m_syscall_count; }
unsigned inode_faults() const { return m_inode_faults; }
void did_inode_fault() { ++m_inode_faults; }
unsigned zero_faults() const { return m_zero_faults; }
void did_zero_fault() { ++m_zero_faults; }
unsigned cow_faults() const { return m_cow_faults; }
void did_cow_fault() { ++m_cow_faults; }
Thread* clone(Process&);
template<typename Callback>
@ -376,6 +385,11 @@ private:
Thread* m_joinee { nullptr };
void* m_exit_value { nullptr };
unsigned m_syscall_count { 0 };
unsigned m_inode_faults { 0 };
unsigned m_zero_faults { 0 };
unsigned m_cow_faults { 0 };
FPUState* m_fpu_state { nullptr };
State m_state { Invalid };
ThreadPriority m_priority { ThreadPriority::Normal };

View file

@ -308,7 +308,7 @@ PageFaultResponse Region::handle_zero_fault(size_t page_index_in_region)
}
if (current)
current->process().did_zero_fault();
current->did_zero_fault();
auto physical_page = MM.allocate_user_physical_page(MemoryManager::ShouldZeroFill::Yes);
if (physical_page.is_null()) {
@ -338,7 +338,7 @@ PageFaultResponse Region::handle_cow_fault(size_t page_index_in_region)
}
if (current)
current->process().did_cow_fault();
current->did_cow_fault();
#ifdef PAGE_FAULT_DEBUG
dbgprintf(" >> It's a COW page and it's time to COW!\n");
@ -382,7 +382,7 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region)
}
if (current)
current->process().did_inode_fault();
current->did_inode_fault();
#ifdef MM_DEBUG
dbgprintf("MM: page_in_from_inode ready to read from inode\n");

View file

@ -38,10 +38,6 @@ HashMap<pid_t, CProcessStatistics> CProcessStatisticsReader::get_all()
process.amount_virtual = process_object.get("amount_virtual").to_u32();
process.amount_resident = process_object.get("amount_resident").to_u32();
process.amount_shared = process_object.get("amount_shared").to_u32();
process.syscall_count = process_object.get("syscall_count").to_u32();
process.inode_faults = process_object.get("inode_faults").to_u32();
process.zero_faults = process_object.get("zero_faults").to_u32();
process.cow_faults = process_object.get("cow_faults").to_u32();
process.icon_id = process_object.get("icon_id").to_int();
auto thread_array = process_object.get("threads").as_array();
@ -53,6 +49,10 @@ HashMap<pid_t, CProcessStatistics> CProcessStatisticsReader::get_all()
thread.state = thread_object.get("state").to_string();
thread.ticks = thread_object.get("ticks").to_u32();
thread.priority = thread_object.get("priority").to_string();
thread.syscall_count = thread_object.get("syscall_count").to_u32();
thread.inode_faults = thread_object.get("inode_faults").to_u32();
thread.zero_faults = thread_object.get("zero_faults").to_u32();
thread.cow_faults = thread_object.get("cow_faults").to_u32();
process.threads.append(move(thread));
});

View file

@ -8,6 +8,10 @@ struct CThreadStatistics {
int tid;
unsigned times_scheduled;
unsigned ticks;
unsigned syscall_count;
unsigned inode_faults;
unsigned zero_faults;
unsigned cow_faults;
String state;
String priority;
};
@ -28,10 +32,6 @@ struct CProcessStatistics {
size_t amount_virtual;
size_t amount_resident;
size_t amount_shared;
unsigned syscall_count;
unsigned inode_faults;
unsigned zero_faults;
unsigned cow_faults;
int icon_id;
Vector<CThreadStatistics> threads;

View file

@ -88,10 +88,10 @@ static Snapshot get_snapshot()
thread_data.amount_virtual = stats.amount_virtual;
thread_data.amount_resident = stats.amount_resident;
thread_data.amount_shared = stats.amount_shared;
thread_data.syscall_count = stats.syscall_count;
thread_data.inode_faults = stats.inode_faults;
thread_data.zero_faults = stats.zero_faults;
thread_data.cow_faults = stats.cow_faults;
thread_data.syscall_count = thread.syscall_count;
thread_data.inode_faults = thread.inode_faults;
thread_data.zero_faults = thread.zero_faults;
thread_data.cow_faults = thread.cow_faults;
thread_data.icon_id = stats.icon_id;
thread_data.times_scheduled = thread.times_scheduled;
thread_data.priority = thread.priority;