1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:27:43 +00:00

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
This commit is contained in:
Andreas Kling 2021-03-02 17:19:35 +01:00
parent b425c2602c
commit ea500dd3e3
5 changed files with 91 additions and 23 deletions

View file

@ -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())