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

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. :^)
This commit is contained in:
Andreas Kling 2023-01-10 17:25:01 +01:00
parent 491edaffc7
commit 5dcc58d54a
4 changed files with 36 additions and 24 deletions

View file

@ -5,37 +5,26 @@
*/
#include <LibCore/Directory.h>
#include <LibCore/ProcessStatisticsReader.h>
#include <LibCore/SessionManagement.h>
#include <LibCore/System.h>
#ifdef AK_OS_SERENITY
# include <LibSystem/syscall.h>
#endif
namespace Core::SessionManagement {
static ErrorOr<Core::ProcessStatistics const*> get_proc(Core::AllProcessesStatistics const& stats, pid_t pid)
ErrorOr<pid_t> root_session_id([[maybe_unused]] Optional<pid_t> force_sid)
{
for (auto& proc : stats.processes) {
if (proc.pid == pid)
return &proc;
#ifdef AK_OS_SERENITY
int rc = syscall(SC_get_root_session_id, force_sid.value_or(-1));
if (rc < 0) {
return Error::from_syscall("get_root_session_id"sv, rc);
}
return Error::from_string_literal("Could not find pid in process statistics.");
}
ErrorOr<pid_t> root_session_id(Optional<pid_t> force_sid)
{
auto stats = TRY(Core::ProcessStatisticsReader::get_all(false));
pid_t sid = (force_sid.has_value()) ? force_sid.value() : TRY(System::getsid());
while (true) {
pid_t parent = TRY(get_proc(stats, sid))->ppid;
pid_t parent_sid = TRY(get_proc(stats, parent))->sid;
if (parent_sid == 0)
break;
sid = parent_sid;
}
return sid;
return static_cast<pid_t>(rc);
#else
return 0;
#endif
}
ErrorOr<void> logout(Optional<pid_t> force_sid)