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/Syscalls | |
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/Syscalls')
-rw-r--r-- | Kernel/Syscalls/profiling.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/Kernel/Syscalls/profiling.cpp b/Kernel/Syscalls/profiling.cpp index 42e1381697..01001fe161 100644 --- a/Kernel/Syscalls/profiling.cpp +++ b/Kernel/Syscalls/profiling.cpp @@ -32,9 +32,25 @@ namespace Kernel { +PerformanceEventBuffer* g_global_perf_events; +bool g_profiling_all_threads; + KResultOr<int> Process::sys$profiling_enable(pid_t pid) { REQUIRE_NO_PROMISES; + + if (pid == -1) { + if (!is_superuser()) + return EPERM; + ScopedCritical critical; + if (g_global_perf_events) + g_global_perf_events->clear(); + else + g_global_perf_events = PerformanceEventBuffer::try_create_with_size(32 * MiB).leak_ptr(); + g_profiling_all_threads = true; + return 0; + } + ScopedSpinLock lock(g_processes_lock); auto process = Process::from_pid(pid); if (!process) @@ -51,6 +67,14 @@ KResultOr<int> Process::sys$profiling_enable(pid_t pid) KResultOr<int> Process::sys$profiling_disable(pid_t pid) { + if (pid == -1) { + if (!is_superuser()) + return EPERM; + ScopedCritical critical; + g_profiling_all_threads = false; + return 0; + } + ScopedSpinLock lock(g_processes_lock); auto process = Process::from_pid(pid); if (!process) |