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).
This commit is contained in:
parent
5461b21c7a
commit
5c0408596f
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user