summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2023-01-10 17:25:01 +0100
committerAndreas Kling <kling@serenityos.org>2023-01-10 19:32:31 +0100
commit5dcc58d54ac7057f092ac9287a853e78015007c8 (patch)
tree4e29874073255df53aca9da8a866eed5a5c0ca52 /Kernel/Syscalls
parent491edaffc708d5174a0126244d3cd99fc05290e3 (diff)
downloadserenity-5dcc58d54ac7057f092ac9287a853e78015007c8.zip
Kernel+LibCore: Make %sid path parsing not take ages
Before this patch, Core::SessionManagement::parse_path_with_sid() would figure out the root session ID by sifting through /sys/kernel/processes. That file can take quite a while to generate (sometimes up to 40ms on my machine, which is a problem on its own!) and with no caching, many of our programs were effectively doing this multiple times on startup when unveiling something in /tmp/session/%sid/ While we should find ways to make generating /sys/kernel/processes fast again, this patch addresses the specific problem by introducing a new syscall: sys$get_root_session_id(). This extracts the root session ID by looking directly at the process table and takes <1ms instead of 40ms. This cuts WebContent process startup time by ~100ms on my machine. :^)
Diffstat (limited to 'Kernel/Syscalls')
-rw-r--r--Kernel/Syscalls/setpgid.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp
index fffdecd749..fd7715c2b3 100644
--- a/Kernel/Syscalls/setpgid.cpp
+++ b/Kernel/Syscalls/setpgid.cpp
@@ -139,4 +139,25 @@ ErrorOr<FlatPtr> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
});
}
+ErrorOr<FlatPtr> Process::sys$get_root_session_id(pid_t force_sid)
+{
+ pid_t sid = (force_sid == -1) ? this->sid().value() : force_sid;
+ if (sid == 0)
+ return 0;
+ while (true) {
+ auto sid_process = Process::from_pid_in_same_jail(sid);
+ if (!sid_process)
+ return ESRCH;
+ auto parent_pid = sid_process->ppid().value();
+ auto parent_process = Process::from_pid_in_same_jail(parent_pid);
+ if (!parent_process)
+ return ESRCH;
+ pid_t parent_sid = parent_process->sid().value();
+ if (parent_sid == 0)
+ break;
+ sid = parent_sid;
+ }
+ return sid;
+}
+
}