mirror of
https://github.com/RGBCube/serenity
synced 2025-05-15 10:04:59 +00:00
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:
parent
712ae73581
commit
5b8cf2ee23
9 changed files with 38 additions and 38 deletions
|
@ -237,10 +237,10 @@ void ProcessModel::update()
|
||||||
ThreadState state;
|
ThreadState state;
|
||||||
state.pid = it.value.pid;
|
state.pid = it.value.pid;
|
||||||
state.user = it.value.username;
|
state.user = it.value.username;
|
||||||
state.syscall_count = it.value.syscall_count;
|
state.syscall_count = thread.syscall_count;
|
||||||
state.inode_faults = it.value.inode_faults;
|
state.inode_faults = thread.inode_faults;
|
||||||
state.zero_faults = it.value.zero_faults;
|
state.zero_faults = thread.zero_faults;
|
||||||
state.cow_faults = it.value.cow_faults;
|
state.cow_faults = thread.cow_faults;
|
||||||
state.name = it.value.name;
|
state.name = it.value.name;
|
||||||
state.amount_virtual = it.value.amount_virtual;
|
state.amount_virtual = it.value.amount_virtual;
|
||||||
state.amount_resident = it.value.amount_resident;
|
state.amount_resident = it.value.amount_resident;
|
||||||
|
|
|
@ -689,10 +689,6 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
|
||||||
process_object.add("amount_virtual", (u32)process.amount_virtual());
|
process_object.add("amount_virtual", (u32)process.amount_virtual());
|
||||||
process_object.add("amount_resident", (u32)process.amount_resident());
|
process_object.add("amount_resident", (u32)process.amount_resident());
|
||||||
process_object.add("amount_shared", (u32)process.amount_shared());
|
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());
|
process_object.add("icon_id", process.icon_id());
|
||||||
auto thread_array = process_object.add_array("threads");
|
auto thread_array = process_object.add_array("threads");
|
||||||
process.for_each_thread([&](const Thread& thread) {
|
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("ticks", thread.ticks());
|
||||||
thread_object.add("state", thread.state_string());
|
thread_object.add("state", thread.state_string());
|
||||||
thread_object.add("priority", to_string(thread.priority()));
|
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;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -286,15 +286,6 @@ public:
|
||||||
|
|
||||||
Lock& big_lock() { return m_big_lock; }
|
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(); }
|
const ELFLoader* elf_loader() const { return m_elf_loader.ptr(); }
|
||||||
|
|
||||||
int icon_id() const { return m_icon_id; }
|
int icon_id() const { return m_icon_id; }
|
||||||
|
@ -373,11 +364,6 @@ private:
|
||||||
|
|
||||||
int m_next_tid { 0 };
|
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;
|
RefPtr<ProcessTracer> m_tracer;
|
||||||
OwnPtr<ELFLoader> m_elf_loader;
|
OwnPtr<ELFLoader> m_elf_loader;
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ int handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_ENABLED();
|
ASSERT_INTERRUPTS_ENABLED();
|
||||||
auto& process = current->process();
|
auto& process = current->process();
|
||||||
process.did_syscall();
|
current->did_syscall();
|
||||||
|
|
||||||
if (function == SC_exit || function == SC_exit_thread) {
|
if (function == SC_exit || function == SC_exit_thread) {
|
||||||
// These syscalls need special handling since they never return to the caller.
|
// These syscalls need special handling since they never return to the caller.
|
||||||
|
|
|
@ -331,6 +331,15 @@ public:
|
||||||
|
|
||||||
void make_thread_specific_region(Badge<Process>);
|
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&);
|
Thread* clone(Process&);
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
|
@ -376,6 +385,11 @@ private:
|
||||||
Thread* m_joinee { nullptr };
|
Thread* m_joinee { nullptr };
|
||||||
void* m_exit_value { 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 };
|
FPUState* m_fpu_state { nullptr };
|
||||||
State m_state { Invalid };
|
State m_state { Invalid };
|
||||||
ThreadPriority m_priority { ThreadPriority::Normal };
|
ThreadPriority m_priority { ThreadPriority::Normal };
|
||||||
|
|
|
@ -308,7 +308,7 @@ PageFaultResponse Region::handle_zero_fault(size_t page_index_in_region)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
current->process().did_zero_fault();
|
current->did_zero_fault();
|
||||||
|
|
||||||
auto physical_page = MM.allocate_user_physical_page(MemoryManager::ShouldZeroFill::Yes);
|
auto physical_page = MM.allocate_user_physical_page(MemoryManager::ShouldZeroFill::Yes);
|
||||||
if (physical_page.is_null()) {
|
if (physical_page.is_null()) {
|
||||||
|
@ -338,7 +338,7 @@ PageFaultResponse Region::handle_cow_fault(size_t page_index_in_region)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
current->process().did_cow_fault();
|
current->did_cow_fault();
|
||||||
|
|
||||||
#ifdef PAGE_FAULT_DEBUG
|
#ifdef PAGE_FAULT_DEBUG
|
||||||
dbgprintf(" >> It's a COW page and it's time to COW!\n");
|
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)
|
if (current)
|
||||||
current->process().did_inode_fault();
|
current->did_inode_fault();
|
||||||
|
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
dbgprintf("MM: page_in_from_inode ready to read from inode\n");
|
dbgprintf("MM: page_in_from_inode ready to read from inode\n");
|
||||||
|
|
|
@ -38,10 +38,6 @@ HashMap<pid_t, CProcessStatistics> CProcessStatisticsReader::get_all()
|
||||||
process.amount_virtual = process_object.get("amount_virtual").to_u32();
|
process.amount_virtual = process_object.get("amount_virtual").to_u32();
|
||||||
process.amount_resident = process_object.get("amount_resident").to_u32();
|
process.amount_resident = process_object.get("amount_resident").to_u32();
|
||||||
process.amount_shared = process_object.get("amount_shared").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();
|
process.icon_id = process_object.get("icon_id").to_int();
|
||||||
|
|
||||||
auto thread_array = process_object.get("threads").as_array();
|
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.state = thread_object.get("state").to_string();
|
||||||
thread.ticks = thread_object.get("ticks").to_u32();
|
thread.ticks = thread_object.get("ticks").to_u32();
|
||||||
thread.priority = thread_object.get("priority").to_string();
|
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));
|
process.threads.append(move(thread));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ struct CThreadStatistics {
|
||||||
int tid;
|
int tid;
|
||||||
unsigned times_scheduled;
|
unsigned times_scheduled;
|
||||||
unsigned ticks;
|
unsigned ticks;
|
||||||
|
unsigned syscall_count;
|
||||||
|
unsigned inode_faults;
|
||||||
|
unsigned zero_faults;
|
||||||
|
unsigned cow_faults;
|
||||||
String state;
|
String state;
|
||||||
String priority;
|
String priority;
|
||||||
};
|
};
|
||||||
|
@ -28,10 +32,6 @@ struct CProcessStatistics {
|
||||||
size_t amount_virtual;
|
size_t amount_virtual;
|
||||||
size_t amount_resident;
|
size_t amount_resident;
|
||||||
size_t amount_shared;
|
size_t amount_shared;
|
||||||
unsigned syscall_count;
|
|
||||||
unsigned inode_faults;
|
|
||||||
unsigned zero_faults;
|
|
||||||
unsigned cow_faults;
|
|
||||||
int icon_id;
|
int icon_id;
|
||||||
|
|
||||||
Vector<CThreadStatistics> threads;
|
Vector<CThreadStatistics> threads;
|
||||||
|
|
|
@ -88,10 +88,10 @@ static Snapshot get_snapshot()
|
||||||
thread_data.amount_virtual = stats.amount_virtual;
|
thread_data.amount_virtual = stats.amount_virtual;
|
||||||
thread_data.amount_resident = stats.amount_resident;
|
thread_data.amount_resident = stats.amount_resident;
|
||||||
thread_data.amount_shared = stats.amount_shared;
|
thread_data.amount_shared = stats.amount_shared;
|
||||||
thread_data.syscall_count = stats.syscall_count;
|
thread_data.syscall_count = thread.syscall_count;
|
||||||
thread_data.inode_faults = stats.inode_faults;
|
thread_data.inode_faults = thread.inode_faults;
|
||||||
thread_data.zero_faults = stats.zero_faults;
|
thread_data.zero_faults = thread.zero_faults;
|
||||||
thread_data.cow_faults = stats.cow_faults;
|
thread_data.cow_faults = thread.cow_faults;
|
||||||
thread_data.icon_id = stats.icon_id;
|
thread_data.icon_id = stats.icon_id;
|
||||||
thread_data.times_scheduled = thread.times_scheduled;
|
thread_data.times_scheduled = thread.times_scheduled;
|
||||||
thread_data.priority = thread.priority;
|
thread_data.priority = thread.priority;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue