kernel/process: move current process to kernel instance
Two functional change: QueryProcessMemory uses the process passed from handle instead current_process Thread::Stop() uses TLS from owner_process instead of current_process
This commit is contained in:
parent
d9342622b0
commit
8fb3d8ff38
19 changed files with 96 additions and 55 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <utility>
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h" // TODO: for current_process. Remove this later
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
|
@ -76,7 +77,9 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
|
|||
if (handle == CurrentThread) {
|
||||
return GetCurrentThread();
|
||||
} else if (handle == CurrentProcess) {
|
||||
return g_current_process;
|
||||
// TODO: should this return HandleTable's parent process, or kernel's current process?
|
||||
// Should change this either way
|
||||
return Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
}
|
||||
|
||||
if (!IsValid(handle)) {
|
||||
|
|
|
@ -30,7 +30,6 @@ KernelSystem::~KernelSystem() {
|
|||
g_handle_table.Clear(); // Free all kernel objects
|
||||
|
||||
Kernel::ThreadingShutdown();
|
||||
g_current_process = nullptr;
|
||||
|
||||
Kernel::TimersShutdown();
|
||||
Kernel::MemoryShutdown();
|
||||
|
@ -48,4 +47,12 @@ u32 KernelSystem::GenerateObjectID() {
|
|||
return next_object_id++;
|
||||
}
|
||||
|
||||
SharedPtr<Process> KernelSystem::GetCurrentProcess() const {
|
||||
return current_process;
|
||||
}
|
||||
|
||||
void KernelSystem::SetCurrentProcess(SharedPtr<Process> process) {
|
||||
current_process = std::move(process);
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
@ -184,6 +184,9 @@ public:
|
|||
/// Retrieves a process from the current list of processes.
|
||||
SharedPtr<Process> GetProcessById(u32 process_id) const;
|
||||
|
||||
SharedPtr<Process> GetCurrentProcess() const;
|
||||
void SetCurrentProcess(SharedPtr<Process> process);
|
||||
|
||||
private:
|
||||
std::unique_ptr<ResourceLimitList> resource_limits;
|
||||
std::atomic<u32> next_object_id{0};
|
||||
|
@ -194,6 +197,8 @@ private:
|
|||
|
||||
// Lists all processes that exist in the current session.
|
||||
std::vector<SharedPtr<Process>> process_list;
|
||||
|
||||
SharedPtr<Process> current_process;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
@ -313,6 +313,4 @@ SharedPtr<Process> KernelSystem::GetProcessById(u32 process_id) const {
|
|||
|
||||
return *itr;
|
||||
}
|
||||
|
||||
SharedPtr<Process> g_current_process;
|
||||
} // namespace Kernel
|
||||
|
|
|
@ -197,6 +197,4 @@ private:
|
|||
friend class KernelSystem;
|
||||
KernelSystem& kernel;
|
||||
};
|
||||
|
||||
extern SharedPtr<Process> g_current_process;
|
||||
} // namespace Kernel
|
||||
|
|
|
@ -52,8 +52,8 @@ SharedPtr<SharedMemory> KernelSystem::CreateSharedMemory(SharedPtr<Process> owne
|
|||
}
|
||||
|
||||
// Refresh the address mappings for the current process.
|
||||
if (Kernel::g_current_process != nullptr) {
|
||||
Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
|
||||
if (current_process != nullptr) {
|
||||
current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
|
||||
}
|
||||
} else {
|
||||
auto& vm_manager = shared_memory->owner_process->vm_manager;
|
||||
|
|
|
@ -83,7 +83,7 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
|
|||
}
|
||||
VMAPermission vma_permissions = (VMAPermission)permissions;
|
||||
|
||||
auto& process = *g_current_process;
|
||||
auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
|
||||
switch (operation & MEMOP_OPERATION_MASK) {
|
||||
case MEMOP_FREE: {
|
||||
|
@ -145,16 +145,17 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
|
|||
}
|
||||
|
||||
static void ExitProcess() {
|
||||
LOG_INFO(Kernel_SVC, "Process {} exiting", g_current_process->process_id);
|
||||
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->process_id);
|
||||
|
||||
ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited");
|
||||
ASSERT_MSG(current_process->status == ProcessStatus::Running, "Process has already exited");
|
||||
|
||||
g_current_process->status = ProcessStatus::Exited;
|
||||
current_process->status = ProcessStatus::Exited;
|
||||
|
||||
// Stop all the process threads that are currently waiting for objects.
|
||||
auto& thread_list = GetThreadList();
|
||||
for (auto& thread : thread_list) {
|
||||
if (thread->owner_process != g_current_process)
|
||||
if (thread->owner_process != current_process)
|
||||
continue;
|
||||
|
||||
if (thread == GetCurrentThread())
|
||||
|
@ -195,7 +196,8 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
|
|||
case MemoryPermission::WriteExecute:
|
||||
case MemoryPermission::ReadWriteExecute:
|
||||
case MemoryPermission::DontCare:
|
||||
return shared_memory->Map(g_current_process.get(), addr, permissions_type,
|
||||
return shared_memory->Map(Core::System::GetInstance().Kernel().GetCurrentProcess().get(),
|
||||
addr, permissions_type,
|
||||
static_cast<MemoryPermission>(other_permissions));
|
||||
default:
|
||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
|
||||
|
@ -213,7 +215,8 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
|
|||
if (shared_memory == nullptr)
|
||||
return ERR_INVALID_HANDLE;
|
||||
|
||||
return shared_memory->Unmap(g_current_process.get(), addr);
|
||||
return shared_memory->Unmap(Core::System::GetInstance().Kernel().GetCurrentProcess().get(),
|
||||
addr);
|
||||
}
|
||||
|
||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||
|
@ -733,14 +736,16 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
|
|||
return ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
|
||||
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
|
||||
SharedPtr<ResourceLimit>& resource_limit = current_process->resource_limit;
|
||||
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
|
||||
return ERR_NOT_AUTHORIZED;
|
||||
}
|
||||
|
||||
if (processor_id == ThreadProcessorIdDefault) {
|
||||
// Set the target CPU to the one specified in the process' exheader.
|
||||
processor_id = g_current_process->ideal_processor;
|
||||
processor_id = current_process->ideal_processor;
|
||||
ASSERT(processor_id != ThreadProcessorIdDefault);
|
||||
}
|
||||
|
||||
|
@ -761,9 +766,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
|
|||
break;
|
||||
}
|
||||
|
||||
CASCADE_RESULT(SharedPtr<Thread> thread, Core::System::GetInstance().Kernel().CreateThread(
|
||||
name, entry_point, priority, arg, processor_id,
|
||||
stack_top, g_current_process));
|
||||
CASCADE_RESULT(SharedPtr<Thread> thread,
|
||||
Core::System::GetInstance().Kernel().CreateThread(
|
||||
name, entry_point, priority, arg, processor_id, stack_top, current_process));
|
||||
|
||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
||||
FPSCR_ROUND_TOZERO); // 0x03C00000
|
||||
|
@ -810,7 +815,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
|||
|
||||
// Note: The kernel uses the current process's resource limit instead of
|
||||
// the one from the thread owner's resource limit.
|
||||
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
|
||||
SharedPtr<ResourceLimit>& resource_limit =
|
||||
Core::System::GetInstance().Kernel().GetCurrentProcess()->resource_limit;
|
||||
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
|
||||
return ERR_NOT_AUTHORIZED;
|
||||
}
|
||||
|
@ -1097,16 +1103,18 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
|
|||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
|
||||
// When trying to create a memory block with address = 0,
|
||||
// if the process has the Shared Device Memory flag in the exheader,
|
||||
// then we have to allocate from the same region as the caller process instead of the BASE
|
||||
// region.
|
||||
MemoryRegion region = MemoryRegion::BASE;
|
||||
if (addr == 0 && g_current_process->flags.shared_device_mem)
|
||||
region = g_current_process->flags.memory_region;
|
||||
if (addr == 0 && current_process->flags.shared_device_mem)
|
||||
region = current_process->flags.memory_region;
|
||||
|
||||
shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory(
|
||||
g_current_process, size, static_cast<MemoryPermission>(my_permission),
|
||||
current_process, size, static_cast<MemoryPermission>(my_permission),
|
||||
static_cast<MemoryPermission>(other_permission), addr, region);
|
||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory)));
|
||||
|
||||
|
@ -1407,8 +1415,9 @@ void CallSVC(u32 immediate) {
|
|||
// Lock the global kernel mutex when we enter the kernel HLE.
|
||||
std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
|
||||
|
||||
ASSERT_MSG(g_current_process->status == ProcessStatus::Running,
|
||||
"Running threads from exiting processes is unimplemented");
|
||||
DEBUG_ASSERT_MSG(Core::System::GetInstance().Kernel().GetCurrentProcess()->status ==
|
||||
ProcessStatus::Running,
|
||||
"Running threads from exiting processes is unimplemented");
|
||||
|
||||
const FunctionDef* info = GetSVCInfo(immediate);
|
||||
if (info) {
|
||||
|
|
|
@ -96,7 +96,7 @@ void Thread::Stop() {
|
|||
u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
|
||||
u32 tls_slot =
|
||||
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
|
||||
Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot);
|
||||
owner_process->tls_slots[tls_page].reset(tls_slot);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,7 +127,7 @@ static void SwitchContext(Thread* new_thread) {
|
|||
// Cancel any outstanding wakeup events for this thread
|
||||
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
|
||||
|
||||
auto previous_process = Kernel::g_current_process;
|
||||
auto previous_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||
|
||||
current_thread = new_thread;
|
||||
|
||||
|
@ -135,8 +135,8 @@ static void SwitchContext(Thread* new_thread) {
|
|||
new_thread->status = ThreadStatus::Running;
|
||||
|
||||
if (previous_process != current_thread->owner_process) {
|
||||
Kernel::g_current_process = current_thread->owner_process;
|
||||
SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
|
||||
Core::System::GetInstance().Kernel().SetCurrentProcess(current_thread->owner_process);
|
||||
SetCurrentPageTable(¤t_thread->owner_process->vm_manager.page_table);
|
||||
}
|
||||
|
||||
Core::CPU().LoadContext(new_thread->context);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue