diff options
author | Andreas Kling <kling@serenityos.org> | 2021-03-02 17:19:35 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-03-02 22:38:06 +0100 |
commit | ea500dd3e31f531212af2e9a33ff40f26de48594 (patch) | |
tree | d70115636c4445ca450a68ea2107427275e1e7f7 /Kernel/Scheduler.cpp | |
parent | b425c2602c6dd10b5509fcd8d81c765b9c76993a (diff) | |
download | serenity-ea500dd3e31f531212af2e9a33ff40f26de48594.zip |
Kernel: Start work on full system profiling :^)
The superuser can now call sys$profiling_enable() with PID -1 to enable
profiling of all running threads in the system. The perf events are
collected in a global PerformanceEventBuffer (currently 32 MiB in size.)
The events can be accessed via /proc/profile
Diffstat (limited to 'Kernel/Scheduler.cpp')
-rw-r--r-- | Kernel/Scheduler.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 0bf6e0b6e0..fb71b6af28 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -42,6 +42,9 @@ namespace Kernel { +extern bool g_profiling_all_threads; +extern PerformanceEventBuffer* g_global_perf_events; + class SchedulerPerProcessorData { AK_MAKE_NONCOPYABLE(SchedulerPerProcessorData); AK_MAKE_NONMOVABLE(SchedulerPerProcessorData); @@ -542,10 +545,22 @@ void Scheduler::timer_tick(const RegisterState& regs) if (!is_bsp) return; // TODO: This prevents scheduling on other CPUs! #endif - if (current_thread->process().is_profiling()) { + + PerformanceEventBuffer* perf_events = nullptr; + + if (g_profiling_all_threads) { + VERIFY(g_global_perf_events); + // FIXME: We currently don't collect samples while idle. + // That will be an interesting mode to add in the future. :^) + if (current_thread != Processor::current().idle_thread()) + perf_events = g_global_perf_events; + } else if (current_thread->process().is_profiling()) { VERIFY(current_thread->process().perf_events()); - auto& perf_events = *current_thread->process().perf_events(); - [[maybe_unused]] auto rc = perf_events.append_with_eip_and_ebp(regs.eip, regs.ebp, PERF_EVENT_SAMPLE, 0, 0); + perf_events = current_thread->process().perf_events(); + } + + if (perf_events) { + [[maybe_unused]] auto rc = perf_events->append_with_eip_and_ebp(regs.eip, regs.ebp, PERF_EVENT_SAMPLE, 0, 0); } if (current_thread->tick()) |