kernel/thread: Use a regular pointer for the owner/current process

There's no real need to use a shared pointer in these cases, and only
makes object management more fragile in terms of how easy it would be to
introduce cycles. Instead, just do the simple thing of using a regular
pointer. Much of this is just a hold-over from citra anyways.

It also doesn't make sense from a behavioral point of view for a
process' thread to prolong the lifetime of the process itself (the
process is supposed to own the thread, not the other way around).
master
Lioncash 2018-10-10 00:42:10 +07:00
parent 5461b21c7a
commit 5c0408596f
10 changed files with 41 additions and 39 deletions

@ -129,7 +129,7 @@ public:
}; };
std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
auto& current_process = Core::CurrentProcess(); auto* current_process = Core::CurrentProcess();
auto** const page_table = current_process->VMManager().page_table.pointers.data(); auto** const page_table = current_process->VMManager().page_table.pointers.data();
Dynarmic::A64::UserConfig config; Dynarmic::A64::UserConfig config;

@ -136,7 +136,8 @@ struct System::Impl {
if (virtual_filesystem == nullptr) if (virtual_filesystem == nullptr)
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
kernel.MakeCurrentProcess(Kernel::Process::Create(kernel, "main")); auto main_process = Kernel::Process::Create(kernel, "main");
kernel.MakeCurrentProcess(main_process.get());
cpu_barrier = std::make_shared<CpuBarrier>(); cpu_barrier = std::make_shared<CpuBarrier>();
cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size()); cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size());
@ -361,11 +362,11 @@ const std::shared_ptr<Kernel::Scheduler>& System::Scheduler(std::size_t core_ind
return impl->cpu_cores[core_index]->Scheduler(); return impl->cpu_cores[core_index]->Scheduler();
} }
Kernel::SharedPtr<Kernel::Process>& System::CurrentProcess() { Kernel::Process* System::CurrentProcess() {
return impl->kernel.CurrentProcess(); return impl->kernel.CurrentProcess();
} }
const Kernel::SharedPtr<Kernel::Process>& System::CurrentProcess() const { const Kernel::Process* System::CurrentProcess() const {
return impl->kernel.CurrentProcess(); return impl->kernel.CurrentProcess();
} }

@ -174,11 +174,11 @@ public:
/// Gets the scheduler for the CPU core with the specified index /// Gets the scheduler for the CPU core with the specified index
const std::shared_ptr<Kernel::Scheduler>& Scheduler(std::size_t core_index); const std::shared_ptr<Kernel::Scheduler>& Scheduler(std::size_t core_index);
/// Provides a reference to the current process /// Provides a pointer to the current process
Kernel::SharedPtr<Kernel::Process>& CurrentProcess(); Kernel::Process* CurrentProcess();
/// Provides a constant reference to the current process. /// Provides a constant pointer to the current process.
const Kernel::SharedPtr<Kernel::Process>& CurrentProcess() const; const Kernel::Process* CurrentProcess() const;
/// Provides a reference to the kernel instance. /// Provides a reference to the kernel instance.
Kernel::KernelCore& Kernel(); Kernel::KernelCore& Kernel();
@ -246,7 +246,7 @@ inline TelemetrySession& Telemetry() {
return System::GetInstance().TelemetrySession(); return System::GetInstance().TelemetrySession();
} }
inline Kernel::SharedPtr<Kernel::Process>& CurrentProcess() { inline Kernel::Process* CurrentProcess() {
return System::GetInstance().CurrentProcess(); return System::GetInstance().CurrentProcess();
} }

@ -116,7 +116,7 @@ struct KernelCore::Impl {
next_thread_id = 1; next_thread_id = 1;
process_list.clear(); process_list.clear();
current_process.reset(); current_process = nullptr;
handle_table.Clear(); handle_table.Clear();
resource_limits.fill(nullptr); resource_limits.fill(nullptr);
@ -207,7 +207,7 @@ struct KernelCore::Impl {
// Lists all processes that exist in the current session. // Lists all processes that exist in the current session.
std::vector<SharedPtr<Process>> process_list; std::vector<SharedPtr<Process>> process_list;
SharedPtr<Process> current_process; Process* current_process = nullptr;
Kernel::HandleTable handle_table; Kernel::HandleTable handle_table;
std::array<SharedPtr<ResourceLimit>, 4> resource_limits; std::array<SharedPtr<ResourceLimit>, 4> resource_limits;
@ -266,15 +266,15 @@ void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
impl->process_list.push_back(std::move(process)); impl->process_list.push_back(std::move(process));
} }
void KernelCore::MakeCurrentProcess(SharedPtr<Process> process) { void KernelCore::MakeCurrentProcess(Process* process) {
impl->current_process = std::move(process); impl->current_process = process;
} }
SharedPtr<Process>& KernelCore::CurrentProcess() { Process* KernelCore::CurrentProcess() {
return impl->current_process; return impl->current_process;
} }
const SharedPtr<Process>& KernelCore::CurrentProcess() const { const Process* KernelCore::CurrentProcess() const {
return impl->current_process; return impl->current_process;
} }

@ -66,13 +66,13 @@ public:
void AppendNewProcess(SharedPtr<Process> process); void AppendNewProcess(SharedPtr<Process> process);
/// Makes the given process the new current process. /// Makes the given process the new current process.
void MakeCurrentProcess(SharedPtr<Process> process); void MakeCurrentProcess(Process* process);
/// Retrieves a reference to the current process. /// Retrieves a pointer to the current process.
SharedPtr<Process>& CurrentProcess(); Process* CurrentProcess();
/// Retrieves a const reference to the current process. /// Retrieves a const pointer to the current process.
const SharedPtr<Process>& CurrentProcess() const; const Process* CurrentProcess() const;
/// Adds a port to the named port table /// Adds a port to the named port table
void AddNamedPort(std::string name, SharedPtr<ClientPort> port); void AddNamedPort(std::string name, SharedPtr<ClientPort> port);

@ -9,7 +9,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/scheduler.h"
@ -78,16 +78,16 @@ void Scheduler::SwitchContext(Thread* new_thread) {
// Cancel any outstanding wakeup events for this thread // Cancel any outstanding wakeup events for this thread
new_thread->CancelWakeupTimer(); new_thread->CancelWakeupTimer();
auto previous_process = Core::CurrentProcess(); auto* const previous_process = Core::CurrentProcess();
current_thread = new_thread; current_thread = new_thread;
ready_queue.remove(new_thread->GetPriority(), new_thread); ready_queue.remove(new_thread->GetPriority(), new_thread);
new_thread->SetStatus(ThreadStatus::Running); new_thread->SetStatus(ThreadStatus::Running);
const auto thread_owner_process = current_thread->GetOwnerProcess(); auto* const thread_owner_process = current_thread->GetOwnerProcess();
if (previous_process != thread_owner_process) { if (previous_process != thread_owner_process) {
Core::CurrentProcess() = thread_owner_process; Core::System::GetInstance().Kernel().MakeCurrentProcess(thread_owner_process);
SetCurrentPageTable(&Core::CurrentProcess()->VMManager().page_table); SetCurrentPageTable(&Core::CurrentProcess()->VMManager().page_table);
} }

@ -341,7 +341,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
info_sub_id, handle); info_sub_id, handle);
const auto& current_process = Core::CurrentProcess(); const auto* current_process = Core::CurrentProcess();
const auto& vm_manager = current_process->VMManager(); const auto& vm_manager = current_process->VMManager();
switch (static_cast<GetInfoType>(info_id)) { switch (static_cast<GetInfoType>(info_id)) {
@ -439,7 +439,7 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
const auto current_process = Core::CurrentProcess(); const auto* current_process = Core::CurrentProcess();
if (thread->GetOwnerProcess() != current_process) { if (thread->GetOwnerProcess() != current_process) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
@ -531,7 +531,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, return shared_memory->Map(Core::CurrentProcess(), addr, permissions_type,
MemoryPermission::DontCare); MemoryPermission::DontCare);
} }
@ -550,7 +550,7 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle);
return shared_memory->Unmap(Core::CurrentProcess().get(), addr); return shared_memory->Unmap(Core::CurrentProcess(), addr);
} }
/// Query process memory /// Query process memory
@ -588,7 +588,7 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
/// Exits the current process /// Exits the current process
static void ExitProcess() { static void ExitProcess() {
auto& current_process = Core::CurrentProcess(); auto* current_process = Core::CurrentProcess();
LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running,
@ -636,7 +636,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
CASCADE_RESULT(SharedPtr<Thread> thread, CASCADE_RESULT(SharedPtr<Thread> thread,
Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top, Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top,
Core::CurrentProcess())); *Core::CurrentProcess()));
const auto new_guest_handle = kernel.HandleTable().Create(thread); const auto new_guest_handle = kernel.HandleTable().Create(thread);
if (new_guest_handle.Failed()) { if (new_guest_handle.Failed()) {
return new_guest_handle.Code(); return new_guest_handle.Code();

@ -194,7 +194,7 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd
ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point, ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
u32 priority, u64 arg, s32 processor_id, u32 priority, u64 arg, s32 processor_id,
VAddr stack_top, SharedPtr<Process> owner_process) { VAddr stack_top, Process& owner_process) {
// Check if priority is in ranged. Lowest priority -> highest priority id. // Check if priority is in ranged. Lowest priority -> highest priority id.
if (priority > THREADPRIO_LOWEST) { if (priority > THREADPRIO_LOWEST) {
LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
@ -208,7 +208,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
// TODO(yuriks): Other checks, returning 0xD9001BEA // TODO(yuriks): Other checks, returning 0xD9001BEA
if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) {
LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
// TODO (bunnei): Find the correct error code to use here // TODO (bunnei): Find the correct error code to use here
return ResultCode(-1); return ResultCode(-1);
@ -232,7 +232,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
thread->wait_handle = 0; thread->wait_handle = 0;
thread->name = std::move(name); thread->name = std::move(name);
thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap(); thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap();
thread->owner_process = owner_process; thread->owner_process = &owner_process;
thread->scheduler = Core::System::GetInstance().Scheduler(processor_id).get(); thread->scheduler = Core::System::GetInstance().Scheduler(processor_id).get();
thread->scheduler->AddThread(thread, priority); thread->scheduler->AddThread(thread, priority);
thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread); thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread);
@ -264,7 +264,7 @@ SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 pri
// Initialize new "main" thread // Initialize new "main" thread
const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress(); const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress();
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
stack_top, &owner_process); stack_top, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); SharedPtr<Thread> thread = std::move(thread_res).Unwrap();

@ -89,7 +89,7 @@ public:
static ResultVal<SharedPtr<Thread>> Create(KernelCore& kernel, std::string name, static ResultVal<SharedPtr<Thread>> Create(KernelCore& kernel, std::string name,
VAddr entry_point, u32 priority, u64 arg, VAddr entry_point, u32 priority, u64 arg,
s32 processor_id, VAddr stack_top, s32 processor_id, VAddr stack_top,
SharedPtr<Process> owner_process); Process& owner_process);
std::string GetName() const override { std::string GetName() const override {
return name; return name;
@ -262,11 +262,11 @@ public:
return processor_id; return processor_id;
} }
SharedPtr<Process>& GetOwnerProcess() { Process* GetOwnerProcess() {
return owner_process; return owner_process;
} }
const SharedPtr<Process>& GetOwnerProcess() const { const Process* GetOwnerProcess() const {
return owner_process; return owner_process;
} }
@ -386,7 +386,7 @@ private:
u64 tpidr_el0 = 0; ///< TPIDR_EL0 read/write system register. u64 tpidr_el0 = 0; ///< TPIDR_EL0 read/write system register.
/// Process that owns this thread /// Process that owns this thread
SharedPtr<Process> owner_process; Process* owner_process;
/// Objects that the thread is waiting on, in the same order as they were /// Objects that the thread is waiting on, in the same order as they were
/// passed to WaitSynchronization1/N. /// passed to WaitSynchronization1/N.

@ -15,7 +15,8 @@ namespace ArmTests {
TestEnvironment::TestEnvironment(bool mutable_memory_) TestEnvironment::TestEnvironment(bool mutable_memory_)
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) { : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
Core::CurrentProcess() = Kernel::Process::Create(kernel, ""); auto process = Kernel::Process::Create(kernel, "");
kernel.MakeCurrentProcess(process.get());
page_table = &Core::CurrentProcess()->VMManager().page_table; page_table = &Core::CurrentProcess()->VMManager().page_table;
std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr); std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr);