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:
Weiyi Wang 2018-10-17 15:23:56 -04:00
parent d9342622b0
commit 8fb3d8ff38
19 changed files with 96 additions and 55 deletions

View file

@ -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)) {

View file

@ -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

View file

@ -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

View file

@ -313,6 +313,4 @@ SharedPtr<Process> KernelSystem::GetProcessById(u32 process_id) const {
return *itr;
}
SharedPtr<Process> g_current_process;
} // namespace Kernel

View file

@ -197,6 +197,4 @@ private:
friend class KernelSystem;
KernelSystem& kernel;
};
extern SharedPtr<Process> g_current_process;
} // namespace Kernel

View file

@ -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;

View file

@ -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) {

View file

@ -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(&current_thread->owner_process->vm_manager.page_table);
}
Core::CPU().LoadContext(new_thread->context);