diff options
author | Andreas Kling <kling@serenityos.org> | 2023-01-10 17:25:01 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-01-10 19:32:31 +0100 |
commit | 5dcc58d54ac7057f092ac9287a853e78015007c8 (patch) | |
tree | 4e29874073255df53aca9da8a866eed5a5c0ca52 /Kernel/Syscalls | |
parent | 491edaffc708d5174a0126244d3cd99fc05290e3 (diff) | |
download | serenity-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.cpp | 21 |
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; +} + } |