mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 08:47:44 +00:00
Kernel: Don't allocate memory for names of processes and threads
Instead, use the FixedCharBuffer class to ensure we always use a static buffer storage for these names. This ensures that if a Process or a Thread were created, there's a guarantee that setting a new name will never fail, as only copying of strings should be done to that static storage. The limits which are set are 32 characters for processes' names and 64 characters for thread names - this is because threads' names could be more verbose than processes' names.
This commit is contained in:
parent
0d30f558f4
commit
3fd4997fc2
22 changed files with 102 additions and 110 deletions
|
@ -30,7 +30,7 @@ static void finalizer_task(void*)
|
|||
|
||||
UNMAP_AFTER_INIT void FinalizerTask::spawn()
|
||||
{
|
||||
auto [_, finalizer_thread] = MUST(Process::create_kernel_process(KString::must_create(finalizer_task_name), finalizer_task, nullptr));
|
||||
auto [_, finalizer_thread] = MUST(Process::create_kernel_process(finalizer_task_name, finalizer_task, nullptr));
|
||||
g_finalizer = move(finalizer_thread);
|
||||
}
|
||||
|
||||
|
|
|
@ -340,7 +340,7 @@ ErrorOr<void> PerformanceEventBuffer::add_process(Process const& process, Proces
|
|||
executable = TRY(process.executable()->try_serialize_absolute_path());
|
||||
} else {
|
||||
executable = TRY(process.name().with([&](auto& process_name) {
|
||||
return KString::formatted("<{}>", process_name->view());
|
||||
return KString::formatted("<{}>", process_name.representable_view());
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
static constexpr StringView power_state_switch_task_name_view = "Power State Switch Task"sv;
|
||||
|
||||
Thread* g_power_state_switch_task;
|
||||
bool g_in_system_shutdown { false };
|
||||
|
||||
|
@ -53,12 +51,9 @@ void PowerStateSwitchTask::power_state_switch_task(void* raw_entry_data)
|
|||
|
||||
void PowerStateSwitchTask::spawn(PowerStateCommand command)
|
||||
{
|
||||
// FIXME: If we switch power states during memory pressure, don't let the system crash just because of our task name.
|
||||
NonnullOwnPtr<KString> power_state_switch_task_name = MUST(KString::try_create(power_state_switch_task_name_view));
|
||||
|
||||
VERIFY(g_power_state_switch_task == nullptr);
|
||||
auto [_, power_state_switch_task_thread] = MUST(Process::create_kernel_process(
|
||||
move(power_state_switch_task_name), power_state_switch_task, bit_cast<void*>(command)));
|
||||
"Power State Switch Task"sv, power_state_switch_task, bit_cast<void*>(command)));
|
||||
g_power_state_switch_task = move(power_state_switch_task_thread);
|
||||
}
|
||||
|
||||
|
@ -189,7 +184,7 @@ ErrorOr<void> PowerStateSwitchTask::kill_processes(ProcessKind kind, ProcessID f
|
|||
if (process.pid() != Process::current().pid() && !process.is_dead() && process.pid() != finalizer_pid && process.is_kernel_process() == kill_kernel_processes) {
|
||||
dbgln("Process {:2} kernel={} dead={} dying={} ({})",
|
||||
process.pid(), process.is_kernel_process(), process.is_dead(), process.is_dying(),
|
||||
process.name().with([](auto& name) { return name->view(); }));
|
||||
process.name().with([](auto& name) { return name.representable_view(); }));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -219,8 +219,7 @@ ErrorOr<Process::ProcessAndFirstThread> Process::create_user_process(StringView
|
|||
}
|
||||
|
||||
auto path_string = TRY(KString::try_create(path));
|
||||
auto name = TRY(KString::try_create(parts.last()));
|
||||
auto [process, first_thread] = TRY(Process::create(move(name), uid, gid, ProcessID(0), false, VirtualFileSystem::the().root_custody(), nullptr, tty));
|
||||
auto [process, first_thread] = TRY(Process::create(parts.last(), uid, gid, ProcessID(0), false, VirtualFileSystem::the().root_custody(), nullptr, tty));
|
||||
|
||||
TRY(process->m_fds.with_exclusive([&](auto& fds) -> ErrorOr<void> {
|
||||
TRY(fds.try_resize(Process::OpenFileDescriptions::max_open()));
|
||||
|
@ -255,9 +254,9 @@ ErrorOr<Process::ProcessAndFirstThread> Process::create_user_process(StringView
|
|||
return ProcessAndFirstThread { move(process), move(first_thread) };
|
||||
}
|
||||
|
||||
ErrorOr<Process::ProcessAndFirstThread> Process::create_kernel_process(NonnullOwnPtr<KString> name, void (*entry)(void*), void* entry_data, u32 affinity, RegisterProcess do_register)
|
||||
ErrorOr<Process::ProcessAndFirstThread> Process::create_kernel_process(StringView name, void (*entry)(void*), void* entry_data, u32 affinity, RegisterProcess do_register)
|
||||
{
|
||||
auto process_and_first_thread = TRY(Process::create(move(name), UserID(0), GroupID(0), ProcessID(0), true));
|
||||
auto process_and_first_thread = TRY(Process::create(name, UserID(0), GroupID(0), ProcessID(0), true));
|
||||
auto& process = *process_and_first_thread.process;
|
||||
auto& thread = *process_and_first_thread.first_thread;
|
||||
|
||||
|
@ -286,13 +285,22 @@ void Process::unprotect_data()
|
|||
});
|
||||
}
|
||||
|
||||
ErrorOr<Process::ProcessAndFirstThread> Process::create(NonnullOwnPtr<KString> name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, Process* fork_parent)
|
||||
ErrorOr<Process::ProcessAndFirstThread> Process::create_with_forked_name(UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, Process* fork_parent)
|
||||
{
|
||||
Process::Name name {};
|
||||
Process::current().name().with([&name](auto& process_name) {
|
||||
name.store_characters(process_name.representable_view());
|
||||
});
|
||||
return TRY(Process::create(name.representable_view(), uid, gid, ppid, is_kernel_process, current_directory, executable, tty, fork_parent));
|
||||
}
|
||||
|
||||
ErrorOr<Process::ProcessAndFirstThread> Process::create(StringView name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, Process* fork_parent)
|
||||
{
|
||||
auto unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) };
|
||||
auto exec_unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) };
|
||||
auto credentials = TRY(Credentials::create(uid, gid, uid, gid, uid, gid, {}, fork_parent ? fork_parent->sid() : 0, fork_parent ? fork_parent->pgid() : 0));
|
||||
|
||||
auto process = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Process(move(name), move(credentials), ppid, is_kernel_process, move(current_directory), move(executable), tty, move(unveil_tree), move(exec_unveil_tree), kgettimeofday())));
|
||||
auto process = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Process(name, move(credentials), ppid, is_kernel_process, move(current_directory), move(executable), tty, move(unveil_tree), move(exec_unveil_tree), kgettimeofday())));
|
||||
|
||||
OwnPtr<Memory::AddressSpace> new_address_space;
|
||||
if (fork_parent) {
|
||||
|
@ -309,9 +317,8 @@ ErrorOr<Process::ProcessAndFirstThread> Process::create(NonnullOwnPtr<KString> n
|
|||
return ProcessAndFirstThread { move(process), move(first_thread) };
|
||||
}
|
||||
|
||||
Process::Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials> credentials, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree, UnixDateTime creation_time)
|
||||
: m_name(move(name))
|
||||
, m_is_kernel_process(is_kernel_process)
|
||||
Process::Process(StringView name, NonnullRefPtr<Credentials> credentials, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree, UnixDateTime creation_time)
|
||||
: m_is_kernel_process(is_kernel_process)
|
||||
, m_executable(move(executable))
|
||||
, m_current_directory(move(current_directory))
|
||||
, m_creation_time(creation_time)
|
||||
|
@ -319,6 +326,7 @@ Process::Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials> credent
|
|||
, m_exec_unveil_data(move(exec_unveil_tree))
|
||||
, m_wait_blocker_set(*this)
|
||||
{
|
||||
set_name(name);
|
||||
// Ensure that we protect the process data when exiting the constructor.
|
||||
with_mutable_protected_data([&](auto& protected_data) {
|
||||
protected_data.pid = allocate_pid();
|
||||
|
@ -329,7 +337,7 @@ Process::Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials> credent
|
|||
|
||||
if constexpr (PROCESS_DEBUG) {
|
||||
this->name().with([&](auto& process_name) {
|
||||
dbgln("Created new process {}({})", process_name->view(), this->pid().value());
|
||||
dbgln("Created new process {}({})", process_name.representable_view(), this->pid().value());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -701,7 +709,7 @@ ErrorOr<void> Process::dump_core()
|
|||
return {};
|
||||
}
|
||||
auto coredump_path = TRY(name().with([&](auto& process_name) {
|
||||
return KString::formatted("{}/{}_{}_{}", coredump_directory_path->view(), process_name->view(), pid().value(), kgettimeofday().seconds_since_epoch());
|
||||
return KString::formatted("{}/{}_{}_{}", coredump_directory_path->view(), process_name.representable_view(), pid().value(), kgettimeofday().seconds_since_epoch());
|
||||
}));
|
||||
auto coredump = TRY(Coredump::try_create(*this, coredump_path->view()));
|
||||
return coredump->write();
|
||||
|
@ -715,7 +723,7 @@ ErrorOr<void> Process::dump_perfcore()
|
|||
|
||||
// Try to generate a filename which isn't already used.
|
||||
auto base_filename = TRY(name().with([&](auto& process_name) {
|
||||
return KString::formatted("{}_{}", process_name->view(), pid().value());
|
||||
return KString::formatted("{}_{}", process_name.representable_view(), pid().value());
|
||||
}));
|
||||
auto perfcore_filename = TRY(KString::formatted("{}.profile", base_filename));
|
||||
RefPtr<OpenFileDescription> description;
|
||||
|
@ -757,7 +765,7 @@ void Process::finalize()
|
|||
|
||||
if (veil_state() == VeilState::Dropped) {
|
||||
name().with([&](auto& process_name) {
|
||||
dbgln("\x1b[01;31mProcess '{}' exited with the veil left open\x1b[0m", process_name->view());
|
||||
dbgln("\x1b[01;31mProcess '{}' exited with the veil left open\x1b[0m", process_name.representable_view());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -888,7 +896,7 @@ void Process::die()
|
|||
if constexpr (PROCESS_DEBUG) {
|
||||
process.name().with([&](auto& process_name) {
|
||||
name().with([&](auto& name) {
|
||||
dbgln("Process {} ({}) is attached by {} ({}) which will exit", process_name->view(), process.pid(), name->view(), pid());
|
||||
dbgln("Process {} ({}) is attached by {} ({}) which will exit", process_name.representable_view(), process.pid(), name.representable_view(), pid());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -896,7 +904,7 @@ void Process::die()
|
|||
auto err = process.send_signal(SIGSTOP, this);
|
||||
if (err.is_error()) {
|
||||
process.name().with([&](auto& process_name) {
|
||||
dbgln("Failed to send the SIGSTOP signal to {} ({})", process_name->view(), process.pid());
|
||||
dbgln("Failed to send the SIGSTOP signal to {} ({})", process_name.representable_view(), process.pid());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -943,14 +951,14 @@ ErrorOr<void> Process::send_signal(u8 signal, Process* sender)
|
|||
return ESRCH;
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<Thread>> Process::create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr<KString> name, u32 affinity, bool joinable)
|
||||
ErrorOr<NonnullRefPtr<Thread>> Process::create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, StringView name, u32 affinity, bool joinable)
|
||||
{
|
||||
VERIFY((priority >= THREAD_PRIORITY_MIN) && (priority <= THREAD_PRIORITY_MAX));
|
||||
|
||||
// FIXME: Do something with guard pages?
|
||||
|
||||
auto thread = TRY(Thread::create(*this));
|
||||
thread->set_name(move(name));
|
||||
thread->set_name(name);
|
||||
thread->set_affinity(affinity);
|
||||
thread->set_priority(priority);
|
||||
if (!joinable)
|
||||
|
@ -1138,15 +1146,15 @@ ErrorOr<NonnullRefPtr<Custody>> Process::custody_for_dirfd(int dirfd)
|
|||
return *description->custody();
|
||||
}
|
||||
|
||||
SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> const& Process::name() const
|
||||
SpinlockProtected<Process::Name, LockRank::None> const& Process::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void Process::set_name(NonnullOwnPtr<KString> name)
|
||||
void Process::set_name(StringView name)
|
||||
{
|
||||
m_name.with([&](auto& this_name) {
|
||||
this_name = move(name);
|
||||
m_name.with([name](auto& process_name) {
|
||||
process_name.store_characters(name);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/FixedStringBuffer.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/IntrusiveList.h>
|
||||
#include <AK/IntrusiveListRelaxedConst.h>
|
||||
|
@ -193,13 +194,13 @@ public:
|
|||
};
|
||||
|
||||
template<typename EntryFunction>
|
||||
static ErrorOr<ProcessAndFirstThread> create_kernel_process(NonnullOwnPtr<KString> name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes)
|
||||
static ErrorOr<ProcessAndFirstThread> create_kernel_process(StringView name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes)
|
||||
{
|
||||
auto* entry_func = new EntryFunction(move(entry));
|
||||
return create_kernel_process(move(name), &Process::kernel_process_trampoline<EntryFunction>, entry_func, affinity, do_register);
|
||||
return create_kernel_process(name, &Process::kernel_process_trampoline<EntryFunction>, entry_func, affinity, do_register);
|
||||
}
|
||||
|
||||
static ErrorOr<ProcessAndFirstThread> create_kernel_process(NonnullOwnPtr<KString> name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes);
|
||||
static ErrorOr<ProcessAndFirstThread> create_kernel_process(StringView name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes);
|
||||
static ErrorOr<ProcessAndFirstThread> create_user_process(StringView path, UserID, GroupID, Vector<NonnullOwnPtr<KString>> arguments, Vector<NonnullOwnPtr<KString>> environment, RefPtr<TTY>);
|
||||
static void register_new(Process&);
|
||||
|
||||
|
@ -207,7 +208,7 @@ public:
|
|||
|
||||
virtual void remove_from_secondary_lists();
|
||||
|
||||
ErrorOr<NonnullRefPtr<Thread>> create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr<KString> name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true);
|
||||
ErrorOr<NonnullRefPtr<Thread>> create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, StringView name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true);
|
||||
|
||||
bool is_profiling() const { return m_profiling; }
|
||||
void set_profiling(bool profiling) { m_profiling = profiling; }
|
||||
|
@ -228,8 +229,9 @@ public:
|
|||
static RefPtr<Process> from_pid_ignoring_jails(ProcessID);
|
||||
static SessionID get_sid_from_pgid(ProcessGroupID pgid);
|
||||
|
||||
SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> const& name() const;
|
||||
void set_name(NonnullOwnPtr<KString>);
|
||||
using Name = FixedStringBuffer<32>;
|
||||
SpinlockProtected<Name, LockRank::None> const& name() const;
|
||||
void set_name(StringView);
|
||||
|
||||
ProcessID pid() const
|
||||
{
|
||||
|
@ -612,8 +614,9 @@ private:
|
|||
bool add_thread(Thread&);
|
||||
bool remove_thread(Thread&);
|
||||
|
||||
Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials>, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree, UnixDateTime creation_time);
|
||||
static ErrorOr<ProcessAndFirstThread> create(NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory = nullptr, RefPtr<Custody> executable = nullptr, RefPtr<TTY> = nullptr, Process* fork_parent = nullptr);
|
||||
Process(StringView name, NonnullRefPtr<Credentials>, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree, UnixDateTime creation_time);
|
||||
static ErrorOr<ProcessAndFirstThread> create_with_forked_name(UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory = nullptr, RefPtr<Custody> executable = nullptr, RefPtr<TTY> = nullptr, Process* fork_parent = nullptr);
|
||||
static ErrorOr<ProcessAndFirstThread> create(StringView name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory = nullptr, RefPtr<Custody> executable = nullptr, RefPtr<TTY> = nullptr, Process* fork_parent = nullptr);
|
||||
ErrorOr<NonnullRefPtr<Thread>> attach_resources(NonnullOwnPtr<Memory::AddressSpace>&&, Process* fork_parent);
|
||||
static ProcessID allocate_pid();
|
||||
|
||||
|
@ -684,7 +687,7 @@ private:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> m_name;
|
||||
SpinlockProtected<Name, LockRank::None> m_name;
|
||||
|
||||
SpinlockProtected<OwnPtr<Memory::AddressSpace>, LockRank::None> m_space;
|
||||
|
||||
|
@ -1046,7 +1049,7 @@ struct AK::Formatter<Kernel::Process> : AK::Formatter<FormatString> {
|
|||
ErrorOr<void> format(FormatBuilder& builder, Kernel::Process const& value)
|
||||
{
|
||||
return value.name().with([&](auto& process_name) {
|
||||
return AK::Formatter<FormatString>::format(builder, "{}({})"sv, process_name->view(), value.pid().value());
|
||||
return AK::Formatter<FormatString>::format(builder, "{}({})"sv, process_name.representable_view(), value.pid().value());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -372,10 +372,10 @@ UNMAP_AFTER_INIT void Scheduler::initialize()
|
|||
g_finalizer_wait_queue = new WaitQueue;
|
||||
|
||||
g_finalizer_has_work.store(false, AK::MemoryOrder::memory_order_release);
|
||||
auto [colonel_process, idle_thread] = MUST(Process::create_kernel_process(KString::must_create("colonel"sv), idle_loop, nullptr, 1, Process::RegisterProcess::No));
|
||||
auto [colonel_process, idle_thread] = MUST(Process::create_kernel_process("colonel"sv, idle_loop, nullptr, 1, Process::RegisterProcess::No));
|
||||
s_colonel_process = &colonel_process.leak_ref();
|
||||
idle_thread->set_priority(THREAD_PRIORITY_MIN);
|
||||
idle_thread->set_name(KString::must_create("Idle Task #0"sv));
|
||||
idle_thread->set_name("Idle Task #0"sv);
|
||||
|
||||
set_idle_thread(idle_thread);
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ UNMAP_AFTER_INIT Thread* Scheduler::create_ap_idle_thread(u32 cpu)
|
|||
VERIFY(Processor::is_bootstrap_processor());
|
||||
|
||||
VERIFY(s_colonel_process);
|
||||
Thread* idle_thread = MUST(s_colonel_process->create_kernel_thread(idle_loop, nullptr, THREAD_PRIORITY_MIN, MUST(KString::formatted("idle thread #{}", cpu)), 1 << cpu, false));
|
||||
Thread* idle_thread = MUST(s_colonel_process->create_kernel_thread(idle_loop, nullptr, THREAD_PRIORITY_MIN, MUST(KString::formatted("idle thread #{}", cpu))->view(), 1 << cpu, false));
|
||||
VERIFY(idle_thread);
|
||||
return idle_thread;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
|||
|
||||
UNMAP_AFTER_INIT void SyncTask::spawn()
|
||||
{
|
||||
MUST(Process::create_kernel_process(KString::must_create("VFS Sync Task"sv), [] {
|
||||
MUST(Process::create_kernel_process("VFS Sync Task"sv, [] {
|
||||
dbgln("VFS SyncTask is running");
|
||||
while (!Process::current().is_dying()) {
|
||||
VirtualFileSystem::sync();
|
||||
|
|
|
@ -47,16 +47,18 @@ ErrorOr<NonnullRefPtr<Thread>> Thread::create(NonnullRefPtr<Process> process)
|
|||
|
||||
auto block_timer = TRY(try_make_ref_counted<Timer>());
|
||||
|
||||
auto name = TRY(process->name().with([](auto& name) { return name->try_clone(); }));
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(process), move(kernel_stack_region), move(block_timer), move(name)));
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(process), move(kernel_stack_region), move(block_timer)));
|
||||
}
|
||||
|
||||
Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer, NonnullOwnPtr<KString> name)
|
||||
Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer)
|
||||
: m_process(move(process))
|
||||
, m_kernel_stack_region(move(kernel_stack_region))
|
||||
, m_name(move(name))
|
||||
, m_block_timer(move(block_timer))
|
||||
{
|
||||
m_process->name().with([this](auto& process_name) {
|
||||
set_name(process_name.representable_view());
|
||||
});
|
||||
|
||||
bool is_first_thread = m_process->add_thread(*this);
|
||||
if (is_first_thread) {
|
||||
// First thread gets TID == PID
|
||||
|
@ -74,7 +76,7 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> ker
|
|||
|
||||
if constexpr (THREAD_DEBUG) {
|
||||
m_process->name().with([&](auto& process_name) {
|
||||
dbgln("Created new thread {}({}:{})", process_name->view(), m_process->pid().value(), m_tid.value());
|
||||
dbgln("Created new thread {}({}:{})", process_name.representable_view(), m_process->pid().value(), m_tid.value());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1465,10 +1467,10 @@ void Thread::track_lock_release(LockRank rank)
|
|||
m_lock_rank_mask ^= rank;
|
||||
}
|
||||
|
||||
void Thread::set_name(NonnullOwnPtr<KString> name)
|
||||
void Thread::set_name(StringView name)
|
||||
{
|
||||
m_name.with([&](auto& this_name) {
|
||||
this_name = move(name);
|
||||
m_name.with([name](auto& thread_name) {
|
||||
thread_name.store_characters(name);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1476,9 +1478,9 @@ void Thread::set_name(NonnullOwnPtr<KString> name)
|
|||
|
||||
ErrorOr<void> AK::Formatter<Kernel::Thread>::format(FormatBuilder& builder, Kernel::Thread const& value)
|
||||
{
|
||||
return value.process().name().with([&](auto& process_name) {
|
||||
return value.process().name().with([&](auto& thread_name) {
|
||||
return AK::Formatter<FormatString>::format(
|
||||
builder,
|
||||
"{}({}:{})"sv, process_name->view(), value.pid().value(), value.tid().value());
|
||||
"{}({}:{})"sv, thread_name.representable_view(), value.pid().value(), value.tid().value());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/Concepts.h>
|
||||
#include <AK/EnumBits.h>
|
||||
#include <AK/Error.h>
|
||||
#include <AK/FixedStringBuffer.h>
|
||||
#include <AK/IntrusiveList.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
|
@ -94,11 +95,13 @@ public:
|
|||
Process& process() { return m_process; }
|
||||
Process const& process() const { return m_process; }
|
||||
|
||||
SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> const& name() const
|
||||
using Name = FixedStringBuffer<64>;
|
||||
SpinlockProtected<Name, LockRank::None> const& name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
void set_name(NonnullOwnPtr<KString> name);
|
||||
|
||||
void set_name(StringView);
|
||||
|
||||
void finalize();
|
||||
|
||||
|
@ -1083,7 +1086,7 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullRefPtr<Timer>, NonnullOwnPtr<KString>);
|
||||
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullRefPtr<Timer>);
|
||||
|
||||
BlockResult block_impl(BlockTimeout const&, Blocker&);
|
||||
|
||||
|
@ -1221,7 +1224,7 @@ private:
|
|||
|
||||
FPUState m_fpu_state {};
|
||||
State m_state { Thread::State::Invalid };
|
||||
SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> m_name;
|
||||
SpinlockProtected<Name, LockRank::None> m_name;
|
||||
u32 m_priority { THREAD_PRIORITY_NORMAL };
|
||||
|
||||
State m_stop_state { Thread::State::Invalid };
|
||||
|
|
|
@ -24,10 +24,7 @@ UNMAP_AFTER_INIT void WorkQueue::initialize()
|
|||
|
||||
UNMAP_AFTER_INIT WorkQueue::WorkQueue(StringView name)
|
||||
{
|
||||
auto name_kstring = KString::try_create(name);
|
||||
if (name_kstring.is_error())
|
||||
TODO();
|
||||
auto [_, thread] = Process::create_kernel_process(name_kstring.release_value(), [this] {
|
||||
auto [_, thread] = Process::create_kernel_process(name, [this] {
|
||||
while (!Process::current().is_dying()) {
|
||||
WorkItem* item;
|
||||
bool have_more;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue