summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-03-02 17:19:35 +0100
committerAndreas Kling <kling@serenityos.org>2021-03-02 22:38:06 +0100
commitea500dd3e31f531212af2e9a33ff40f26de48594 (patch)
treed70115636c4445ca450a68ea2107427275e1e7f7 /Kernel/Syscalls
parentb425c2602c6dd10b5509fcd8d81c765b9c76993a (diff)
downloadserenity-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.cpp24
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)