summaryrefslogtreecommitdiff
path: root/Kernel/Thread.cpp
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2021-07-14 21:46:32 -0600
committerAndreas Kling <kling@serenityos.org>2021-07-18 22:08:26 +0200
commita635ff4e600729fb7d12fdd16ac6ffbaa455bb30 (patch)
tree8625e110b4c9ca2510c3a8ac28b45bddae828af7 /Kernel/Thread.cpp
parent7e77a2ec40bc339f41e75aa9fdc6744df449612c (diff)
downloadserenity-a635ff4e600729fb7d12fdd16ac6ffbaa455bb30.zip
Everywhere: Make tracking cpu usage independent from system ticks
This switches tracking CPU usage to more accurately measure time in user and kernel land using either the TSC or another time source. This will also come in handy when implementing a tickless kernel mode.
Diffstat (limited to 'Kernel/Thread.cpp')
-rw-r--r--Kernel/Thread.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp
index b3e0b53158..6d5111a1bd 100644
--- a/Kernel/Thread.cpp
+++ b/Kernel/Thread.cpp
@@ -567,6 +567,29 @@ void Thread::finalize_dying_threads()
}
}
+void Thread::update_time_scheduled(u64 current_scheduler_time, bool is_kernel, bool no_longer_running)
+{
+ if (m_last_time_scheduled.has_value()) {
+ u64 delta;
+ if (current_scheduler_time >= m_last_time_scheduled.value())
+ delta = current_scheduler_time - m_last_time_scheduled.value();
+ else
+ delta = m_last_time_scheduled.value() - current_scheduler_time; // the unlikely event that the clock wrapped
+ if (delta != 0) {
+ // Add it to the global total *before* updating the thread's value!
+ Scheduler::add_time_scheduled(delta, is_kernel);
+
+ auto& total_time = is_kernel ? m_total_time_scheduled_kernel : m_total_time_scheduled_user;
+ ScopedSpinLock scheduler_lock(g_scheduler_lock);
+ total_time += delta;
+ }
+ }
+ if (no_longer_running)
+ m_last_time_scheduled = {};
+ else
+ m_last_time_scheduled = current_scheduler_time;
+}
+
bool Thread::tick()
{
if (previous_mode() == PreviousMode::KernelMode) {