diff --git a/AK/Format.cpp b/AK/Format.cpp index 9835b3ef4ef..757b3f5406b 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -920,7 +920,7 @@ void vdbg(StringView fmtstr, TypeErasedFormatParams& params, bool newline) if (Kernel::Thread::current()) { auto& thread = *Kernel::Thread::current(); thread.process().name().with([&](auto& process_name) { - builder.appendff("{}.{:03} \033[34;1m[#{} {}({}:{})]\033[0m: ", time.truncated_seconds(), time.nanoseconds_within_second() / 1000000, Kernel::Processor::current_id(), process_name->view(), thread.pid().value(), thread.tid().value()); + builder.appendff("{}.{:03} \033[34;1m[#{} {}({}:{})]\033[0m: ", time.truncated_seconds(), time.nanoseconds_within_second() / 1000000, Kernel::Processor::current_id(), process_name.representable_view(), thread.pid().value(), thread.tid().value()); }); } else { builder.appendff("{}.{:03} \033[34;1m[#{} Kernel]\033[0m: ", time.truncated_seconds(), time.nanoseconds_within_second() / 1000000, Kernel::Processor::current_id()); @@ -974,7 +974,7 @@ void vdmesgln(StringView fmtstr, TypeErasedFormatParams& params) if (Kernel::Processor::is_initialized() && Kernel::Thread::current()) { auto& thread = *Kernel::Thread::current(); thread.process().name().with([&](auto& process_name) { - builder.appendff("{}.{:03} \033[34;1m[{}({}:{})]\033[0m: ", time.truncated_seconds(), time.nanoseconds_within_second() / 1000000, process_name->view(), thread.pid().value(), thread.tid().value()); + builder.appendff("{}.{:03} \033[34;1m[{}({}:{})]\033[0m: ", time.truncated_seconds(), time.nanoseconds_within_second() / 1000000, process_name.representable_view(), thread.pid().value(), thread.tid().value()); }); } else { builder.appendff("{}.{:03} \033[34;1m[Kernel]\033[0m: ", time.truncated_seconds(), time.nanoseconds_within_second() / 1000000); @@ -1001,7 +1001,7 @@ void v_critical_dmesgln(StringView fmtstr, TypeErasedFormatParams& params) if (Kernel::Processor::is_initialized() && Kernel::Thread::current()) { auto& thread = *Kernel::Thread::current(); thread.process().name().with([&](auto& process_name) { - builder.appendff("[{}({}:{})]: ", process_name->view(), thread.pid().value(), thread.tid().value()); + builder.appendff("[{}({}:{})]: ", process_name.representable_view(), thread.pid().value(), thread.tid().value()); }); } else { builder.appendff("[Kernel]: "); diff --git a/Kernel/Arch/init.cpp b/Kernel/Arch/init.cpp index 0f73c0ef9b3..91ff95862d7 100644 --- a/Kernel/Arch/init.cpp +++ b/Kernel/Arch/init.cpp @@ -298,7 +298,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con } #endif - MUST(Process::create_kernel_process(KString::must_create("init_stage2"sv), init_stage2, nullptr, THREAD_AFFINITY_DEFAULT, Process::RegisterProcess::No)); + MUST(Process::create_kernel_process("init_stage2"sv, init_stage2, nullptr, THREAD_AFFINITY_DEFAULT, Process::RegisterProcess::No)); Scheduler::start(); VERIFY_NOT_REACHED(); diff --git a/Kernel/Bus/USB/UHCI/UHCIController.cpp b/Kernel/Bus/USB/UHCI/UHCIController.cpp index a98bdab23a4..e3d38a8f3c1 100644 --- a/Kernel/Bus/USB/UHCI/UHCIController.cpp +++ b/Kernel/Bus/USB/UHCI/UHCIController.cpp @@ -585,7 +585,7 @@ size_t UHCIController::poll_transfer_queue(QueueHead& transfer_queue) ErrorOr UHCIController::spawn_port_process() { - TRY(Process::create_kernel_process(TRY(KString::try_create("UHCI Hot Plug Task"sv)), [&] { + TRY(Process::create_kernel_process("UHCI Hot Plug Task"sv, [&] { while (!Process::current().is_dying()) { if (m_root_hub) m_root_hub->check_for_port_updates(); @@ -600,7 +600,7 @@ ErrorOr UHCIController::spawn_port_process() ErrorOr UHCIController::spawn_async_poll_process() { - TRY(Process::create_kernel_process(TRY(KString::try_create("UHCI Async Poll Task"sv)), [&] { + TRY(Process::create_kernel_process("UHCI Async Poll Task"sv, [&] { u16 poll_interval_ms = 1024; while (!Process::current().is_dying()) { { diff --git a/Kernel/FileSystem/Plan9FS/FileSystem.cpp b/Kernel/FileSystem/Plan9FS/FileSystem.cpp index 8a6796344da..6adfa69a2b0 100644 --- a/Kernel/FileSystem/Plan9FS/FileSystem.cpp +++ b/Kernel/FileSystem/Plan9FS/FileSystem.cpp @@ -350,10 +350,7 @@ void Plan9FS::ensure_thread() { SpinlockLocker lock(m_thread_lock); if (!m_thread_running.exchange(true, AK::MemoryOrder::memory_order_acq_rel)) { - auto process_name = KString::try_create("Plan9FS"sv); - if (process_name.is_error()) - TODO(); - auto [_, thread] = Process::create_kernel_process(process_name.release_value(), [&]() { + auto [_, thread] = Process::create_kernel_process("Plan9FS"sv, [&]() { thread_main(); m_thread_running.store(false, AK::MemoryOrder::memory_order_release); Process::current().sys$exit(0); diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp index c07618cb8c4..a9f33351b12 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp @@ -81,7 +81,7 @@ ErrorOr SysFSOverallProcesses::try_generate(KBufferBuilder& builder) } else { TRY(process_object.add("tty"sv, "")); } - TRY(process.name().with([&](auto& process_name) { return process_object.add("name"sv, process_name->view()); })); + TRY(process.name().with([&](auto& process_name) { return process_object.add("name"sv, process_name.representable_view()); })); TRY(process_object.add("executable"sv, process.executable() ? TRY(process.executable()->try_serialize_absolute_path())->view() : ""sv)); TRY(process_object.add("creation_time"sv, process.creation_time().nanoseconds_since_epoch())); @@ -121,7 +121,7 @@ ErrorOr SysFSOverallProcesses::try_generate(KBufferBuilder& builder) TRY(thread_object.add("lock_count"sv, thread.lock_count())); #endif TRY(thread_object.add("tid"sv, thread.tid().value())); - TRY(thread.name().with([&](auto& thread_name) { return thread_object.add("name"sv, thread_name->view()); })); + TRY(thread.name().with([&](auto& thread_name) { return thread_object.add("name"sv, thread_name.representable_view()); })); TRY(thread_object.add("times_scheduled"sv, thread.times_scheduled())); TRY(thread_object.add("time_user"sv, thread.time_in_user())); TRY(thread_object.add("time_kernel"sv, thread.time_in_kernel())); diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index 6c1469b84fb..40f29eccd68 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -904,7 +904,7 @@ ErrorOr MemoryManager::commit_physical_pages(size_t pa }); process.name().with([&](auto& process_name) { dbgln("{}({}) resident:{}, shared:{}, virtual:{}", - process_name->view(), + process_name.representable_view(), process.pid(), amount_resident / PAGE_SIZE, amount_shared / PAGE_SIZE, diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp index cf5636b7806..66b6498220d 100644 --- a/Kernel/Net/NetworkTask.cpp +++ b/Kernel/Net/NetworkTask.cpp @@ -42,10 +42,7 @@ static HashTable>* delayed_ack_sockets; void NetworkTask::spawn() { - auto name = KString::try_create("Network Task"sv); - if (name.is_error()) - TODO(); - auto [_, first_thread] = MUST(Process::create_kernel_process(name.release_value(), NetworkTask_main, nullptr)); + auto [_, first_thread] = MUST(Process::create_kernel_process("Network Task"sv, NetworkTask_main, nullptr)); network_task = first_thread; } diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index e818c0df747..7e0b434094b 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -480,9 +480,6 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d auto last_part = path->view().find_last_split_view('/'); - auto new_process_name = TRY(KString::try_create(last_part)); - auto new_main_thread_name = TRY(new_process_name->try_clone()); - auto allocated_space = TRY(Memory::AddressSpace::try_create(*this, nullptr)); OwnPtr old_space; auto old_master_tls_region = m_master_tls_region; @@ -659,8 +656,9 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d // and we don't want to deal with faults after this point. auto new_userspace_sp = TRY(make_userspace_context_for_main_thread(new_main_thread->regs(), *load_result.stack_region.unsafe_ptr(), m_arguments, m_environment, move(auxv))); - set_name(move(new_process_name)); - new_main_thread->set_name(move(new_main_thread_name)); + // NOTE: The Process and its first thread share the same name. + set_name(last_part); + new_main_thread->set_name(last_part); if (wait_for_tracer_at_next_execve()) { // Make sure we release the ptrace lock here or the tracer will block forever. diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index a1481320070..219c0726a7f 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -20,9 +20,8 @@ ErrorOr Process::sys$fork(RegisterState& regs) VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::proc)); - auto child_name = TRY(name().with([](auto& name) { return name->try_clone(); })); auto credentials = this->credentials(); - auto child_and_first_thread = TRY(Process::create(move(child_name), credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), tty(), this)); + auto child_and_first_thread = TRY(Process::create_with_forked_name(credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), tty(), this)); auto& child = child_and_first_thread.process; auto& child_first_thread = child_and_first_thread.first_thread; diff --git a/Kernel/Syscalls/kill.cpp b/Kernel/Syscalls/kill.cpp index 7cbcaa68434..84491f6a663 100644 --- a/Kernel/Syscalls/kill.cpp +++ b/Kernel/Syscalls/kill.cpp @@ -22,7 +22,7 @@ ErrorOr Process::do_kill(Process& process, int signal) return EPERM; if (process.is_kernel_process()) { process.name().with([&](auto& process_name) { - dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process_name->view(), process.pid()); + dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process_name.representable_view(), process.pid()); }); return EPERM; } diff --git a/Kernel/Syscalls/prctl.cpp b/Kernel/Syscalls/prctl.cpp index 4eeabe2d142..5fdd60d9e74 100644 --- a/Kernel/Syscalls/prctl.cpp +++ b/Kernel/Syscalls/prctl.cpp @@ -55,14 +55,13 @@ ErrorOr Process::sys$prctl(int option, FlatPtr arg1, FlatPtr arg2) int user_buffer_size = static_cast(arg2); if (user_buffer_size < 0) return EINVAL; - if (user_buffer_size > 256) - return ENAMETOOLONG; size_t buffer_size = static_cast(user_buffer_size); - auto name = TRY(try_copy_kstring_from_user(buffer, buffer_size)); + Process::Name process_name {}; + TRY(try_copy_name_from_user_into_fixed_string_buffer<32>(buffer, process_name, buffer_size)); // NOTE: Reject empty and whitespace-only names, as they only confuse users. - if (name->view().is_whitespace()) + if (process_name.representable_view().is_whitespace()) return EINVAL; - set_name(move(name)); + set_name(process_name.representable_view()); return 0; } case PR_GET_PROCESS_NAME: { @@ -73,9 +72,10 @@ ErrorOr Process::sys$prctl(int option, FlatPtr arg1, FlatPtr arg2) return EINVAL; size_t buffer_size = static_cast(arg2); TRY(m_name.with([&buffer, buffer_size](auto& name) -> ErrorOr { - if (name->length() + 1 > buffer_size) + auto view = name.representable_view(); + if (view.length() + 1 > buffer_size) return ENAMETOOLONG; - return copy_to_user(buffer, name->characters(), name->length() + 1); + return copy_to_user(buffer, view.characters_without_null_termination(), view.length() + 1); })); return 0; } diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index 7017012f853..7c6f2ae317a 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -48,9 +48,9 @@ ErrorOr Process::sys$create_thread(void* (*entry)(void*), Userspaceview(), thread->tid().value()); + return KString::formatted("{} [{}]", process_name.representable_view(), thread->tid().value()); })); - thread->set_name(move(new_thread_name)); + thread->set_name(new_thread_name->view()); if (!is_thread_joinable) thread->detach(); @@ -194,17 +194,14 @@ ErrorOr Process::sys$set_thread_name(pid_t tid, Userspace VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::stdio)); - auto name = TRY(try_copy_kstring_from_user(user_name, user_name_length)); - - const size_t max_thread_name_size = 64; - if (name->length() > max_thread_name_size) - return ENAMETOOLONG; + Thread::Name thread_name {}; + TRY(try_copy_name_from_user_into_fixed_string_buffer<64>(user_name, thread_name, user_name_length)); auto thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) return ESRCH; - thread->set_name(move(name)); + thread->set_name(thread_name.representable_view()); return 0; } @@ -220,16 +217,12 @@ ErrorOr Process::sys$get_thread_name(pid_t tid, Userspace buffer return ESRCH; TRY(thread->name().with([&](auto& thread_name) -> ErrorOr { - if (thread_name->view().is_null()) { - char null_terminator = '\0'; - TRY(copy_to_user(buffer, &null_terminator, sizeof(null_terminator))); - return {}; - } - - if (thread_name->length() + 1 > buffer_size) + VERIFY(!thread_name.representable_view().is_null()); + auto thread_name_view = thread_name.representable_view(); + if (thread_name_view.length() + 1 > buffer_size) return ENAMETOOLONG; - return copy_to_user(buffer, thread_name->characters(), thread_name->length() + 1); + return copy_to_user(buffer, thread_name_view.characters_without_null_termination(), thread_name_view.length() + 1); })); return 0; diff --git a/Kernel/Tasks/FinalizerTask.cpp b/Kernel/Tasks/FinalizerTask.cpp index 2fccea664a0..9586a9b4ea4 100644 --- a/Kernel/Tasks/FinalizerTask.cpp +++ b/Kernel/Tasks/FinalizerTask.cpp @@ -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); } diff --git a/Kernel/Tasks/PerformanceEventBuffer.cpp b/Kernel/Tasks/PerformanceEventBuffer.cpp index 7a67708e103..f0087e1ae45 100644 --- a/Kernel/Tasks/PerformanceEventBuffer.cpp +++ b/Kernel/Tasks/PerformanceEventBuffer.cpp @@ -340,7 +340,7 @@ ErrorOr 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()); })); } diff --git a/Kernel/Tasks/PowerStateSwitchTask.cpp b/Kernel/Tasks/PowerStateSwitchTask.cpp index 5d304e1c01c..a12bc640528 100644 --- a/Kernel/Tasks/PowerStateSwitchTask.cpp +++ b/Kernel/Tasks/PowerStateSwitchTask.cpp @@ -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 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(command))); + "Power State Switch Task"sv, power_state_switch_task, bit_cast(command))); g_power_state_switch_task = move(power_state_switch_task_thread); } @@ -189,7 +184,7 @@ ErrorOr 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(); })); } }); } diff --git a/Kernel/Tasks/Process.cpp b/Kernel/Tasks/Process.cpp index 9834b7c98b7..2c7651c59bc 100644 --- a/Kernel/Tasks/Process.cpp +++ b/Kernel/Tasks/Process.cpp @@ -219,8 +219,7 @@ ErrorOr 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 { TRY(fds.try_resize(Process::OpenFileDescriptions::max_open())); @@ -255,9 +254,9 @@ ErrorOr Process::create_user_process(StringView return ProcessAndFirstThread { move(process), move(first_thread) }; } -ErrorOr Process::create_kernel_process(NonnullOwnPtr name, void (*entry)(void*), void* entry_data, u32 affinity, RegisterProcess do_register) +ErrorOr 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::create(NonnullOwnPtr name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, Process* fork_parent) +ErrorOr Process::create_with_forked_name(UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr 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::create(StringView name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr 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 new_address_space; if (fork_parent) { @@ -309,9 +317,8 @@ ErrorOr Process::create(NonnullOwnPtr n return ProcessAndFirstThread { move(process), move(first_thread) }; } -Process::Process(NonnullOwnPtr name, NonnullRefPtr credentials, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr 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, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr 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 name, NonnullRefPtr 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 name, NonnullRefPtr 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 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 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 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 Process::send_signal(u8 signal, Process* sender) return ESRCH; } -ErrorOr> Process::create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr name, u32 affinity, bool joinable) +ErrorOr> 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> Process::custody_for_dirfd(int dirfd) return *description->custody(); } -SpinlockProtected, LockRank::None> const& Process::name() const +SpinlockProtected const& Process::name() const { return m_name; } -void Process::set_name(NonnullOwnPtr 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); }); } diff --git a/Kernel/Tasks/Process.h b/Kernel/Tasks/Process.h index c1331dfb001..ffb3e42646b 100644 --- a/Kernel/Tasks/Process.h +++ b/Kernel/Tasks/Process.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include #include @@ -193,13 +194,13 @@ public: }; template - static ErrorOr create_kernel_process(NonnullOwnPtr name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes) + static ErrorOr 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, entry_func, affinity, do_register); + return create_kernel_process(name, &Process::kernel_process_trampoline, entry_func, affinity, do_register); } - static ErrorOr create_kernel_process(NonnullOwnPtr name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes); + static ErrorOr create_kernel_process(StringView name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes); static ErrorOr create_user_process(StringView path, UserID, GroupID, Vector> arguments, Vector> environment, RefPtr); static void register_new(Process&); @@ -207,7 +208,7 @@ public: virtual void remove_from_secondary_lists(); - ErrorOr> create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true); + ErrorOr> 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 from_pid_ignoring_jails(ProcessID); static SessionID get_sid_from_pgid(ProcessGroupID pgid); - SpinlockProtected, LockRank::None> const& name() const; - void set_name(NonnullOwnPtr); + using Name = FixedStringBuffer<32>; + SpinlockProtected 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 name, NonnullRefPtr, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree, UnixDateTime creation_time); - static ErrorOr create(NonnullOwnPtr name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr current_directory = nullptr, RefPtr executable = nullptr, RefPtr = nullptr, Process* fork_parent = nullptr); + Process(StringView name, NonnullRefPtr, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree, UnixDateTime creation_time); + static ErrorOr create_with_forked_name(UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr current_directory = nullptr, RefPtr executable = nullptr, RefPtr = nullptr, Process* fork_parent = nullptr); + static ErrorOr create(StringView name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr current_directory = nullptr, RefPtr executable = nullptr, RefPtr = nullptr, Process* fork_parent = nullptr); ErrorOr> attach_resources(NonnullOwnPtr&&, Process* fork_parent); static ProcessID allocate_pid(); @@ -684,7 +687,7 @@ private: return nullptr; } - SpinlockProtected, LockRank::None> m_name; + SpinlockProtected m_name; SpinlockProtected, LockRank::None> m_space; @@ -1046,7 +1049,7 @@ struct AK::Formatter : AK::Formatter { ErrorOr format(FormatBuilder& builder, Kernel::Process const& value) { return value.name().with([&](auto& process_name) { - return AK::Formatter::format(builder, "{}({})"sv, process_name->view(), value.pid().value()); + return AK::Formatter::format(builder, "{}({})"sv, process_name.representable_view(), value.pid().value()); }); } }; diff --git a/Kernel/Tasks/Scheduler.cpp b/Kernel/Tasks/Scheduler.cpp index 9bb7821b5c8..86b42000fbf 100644 --- a/Kernel/Tasks/Scheduler.cpp +++ b/Kernel/Tasks/Scheduler.cpp @@ -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; } diff --git a/Kernel/Tasks/SyncTask.cpp b/Kernel/Tasks/SyncTask.cpp index d7574b3aeff..9e7b87d6ffe 100644 --- a/Kernel/Tasks/SyncTask.cpp +++ b/Kernel/Tasks/SyncTask.cpp @@ -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(); diff --git a/Kernel/Tasks/Thread.cpp b/Kernel/Tasks/Thread.cpp index c47ccc145a3..813284fb5b5 100644 --- a/Kernel/Tasks/Thread.cpp +++ b/Kernel/Tasks/Thread.cpp @@ -47,16 +47,18 @@ ErrorOr> Thread::create(NonnullRefPtr process) auto block_timer = TRY(try_make_ref_counted()); - 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, NonnullOwnPtr kernel_stack_region, NonnullRefPtr block_timer, NonnullOwnPtr name) +Thread::Thread(NonnullRefPtr process, NonnullOwnPtr kernel_stack_region, NonnullRefPtr 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, NonnullOwnPtr 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 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 name) ErrorOr AK::Formatter::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::format( builder, - "{}({}:{})"sv, process_name->view(), value.pid().value(), value.tid().value()); + "{}({}:{})"sv, thread_name.representable_view(), value.pid().value(), value.tid().value()); }); } diff --git a/Kernel/Tasks/Thread.h b/Kernel/Tasks/Thread.h index 74d33a89b6d..cec430fe665 100644 --- a/Kernel/Tasks/Thread.h +++ b/Kernel/Tasks/Thread.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -94,11 +95,13 @@ public: Process& process() { return m_process; } Process const& process() const { return m_process; } - SpinlockProtected, LockRank::None> const& name() const + using Name = FixedStringBuffer<64>; + SpinlockProtected const& name() const { return m_name; } - void set_name(NonnullOwnPtr name); + + void set_name(StringView); void finalize(); @@ -1083,7 +1086,7 @@ public: #endif private: - Thread(NonnullRefPtr, NonnullOwnPtr, NonnullRefPtr, NonnullOwnPtr); + Thread(NonnullRefPtr, NonnullOwnPtr, NonnullRefPtr); BlockResult block_impl(BlockTimeout const&, Blocker&); @@ -1221,7 +1224,7 @@ private: FPUState m_fpu_state {}; State m_state { Thread::State::Invalid }; - SpinlockProtected, LockRank::None> m_name; + SpinlockProtected m_name; u32 m_priority { THREAD_PRIORITY_NORMAL }; State m_stop_state { Thread::State::Invalid }; diff --git a/Kernel/Tasks/WorkQueue.cpp b/Kernel/Tasks/WorkQueue.cpp index e9102d0ce80..bf88875e1c5 100644 --- a/Kernel/Tasks/WorkQueue.cpp +++ b/Kernel/Tasks/WorkQueue.cpp @@ -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;