hle: kernel: Migrate KProcess to KAutoObject.
This commit is contained in:
parent
5e5933256b
commit
7ccbdd4d8d
14 changed files with 80 additions and 58 deletions
|
@ -233,8 +233,11 @@ struct System::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
||||||
auto main_process =
|
auto main_process = Kernel::Process::CreateWithKernel(system.Kernel());
|
||||||
Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland);
|
ASSERT(Kernel::Process::Initialize(main_process, system, "main",
|
||||||
|
Kernel::Process::ProcessType::Userland)
|
||||||
|
.IsSuccess());
|
||||||
|
main_process->Open();
|
||||||
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
||||||
if (load_result != Loader::ResultStatus::Success) {
|
if (load_result != Loader::ResultStatus::Success) {
|
||||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
||||||
|
@ -244,7 +247,7 @@ struct System::Impl {
|
||||||
static_cast<u32>(load_result));
|
static_cast<u32>(load_result));
|
||||||
}
|
}
|
||||||
AddGlueRegistrationForProcess(*app_loader, *main_process);
|
AddGlueRegistrationForProcess(*app_loader, *main_process);
|
||||||
kernel.MakeCurrentProcess(main_process.get());
|
kernel.MakeCurrentProcess(main_process);
|
||||||
kernel.InitializeCores();
|
kernel.InitializeCores();
|
||||||
|
|
||||||
// Initialize cheat engine
|
// Initialize cheat engine
|
||||||
|
|
|
@ -100,7 +100,7 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||||
std::shared_ptr<Object> object = GetGeneric(handle);
|
std::shared_ptr<Object> object = SharedFrom(GetGeneric(handle));
|
||||||
if (object == nullptr) {
|
if (object == nullptr) {
|
||||||
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
||||||
return ResultInvalidHandle;
|
return ResultInvalidHandle;
|
||||||
|
@ -140,17 +140,17 @@ bool HandleTable::IsValid(Handle handle) const {
|
||||||
return slot < table_size && is_object_valid && generations[slot] == generation;
|
return slot < table_size && is_object_valid && generations[slot] == generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
|
Object* HandleTable::GetGeneric(Handle handle) const {
|
||||||
if (handle == CurrentThread) {
|
if (handle == CurrentThread) {
|
||||||
return SharedFrom(kernel.CurrentScheduler()->GetCurrentThread());
|
return (kernel.CurrentScheduler()->GetCurrentThread());
|
||||||
} else if (handle == CurrentProcess) {
|
} else if (handle == CurrentProcess) {
|
||||||
return SharedFrom(kernel.CurrentProcess());
|
return (kernel.CurrentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid(handle)) {
|
if (!IsValid(handle)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return objects[GetSlot(handle)];
|
return objects[GetSlot(handle)].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleTable::Clear() {
|
void HandleTable::Clear() {
|
||||||
|
|
|
@ -98,7 +98,7 @@ public:
|
||||||
* Looks up a handle.
|
* Looks up a handle.
|
||||||
* @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
|
* @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<Object> GetGeneric(Handle handle) const;
|
Object* GetGeneric(Handle handle) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a handle while verifying its type.
|
* Looks up a handle while verifying its type.
|
||||||
|
@ -106,7 +106,7 @@ public:
|
||||||
* type differs from the requested one.
|
* type differs from the requested one.
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
std::shared_ptr<T> Get(Handle handle) const {
|
T* Get(Handle handle) const {
|
||||||
return DynamicObjectCast<T>(GetGeneric(handle));
|
return DynamicObjectCast<T>(GetGeneric(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,16 @@
|
||||||
#include "core/hle/kernel/k_system_control.h"
|
#include "core/hle/kernel/k_system_control.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/memory_types.h"
|
#include "core/hle/kernel/memory_types.h"
|
||||||
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace Kernel::Init {
|
namespace Kernel::Init {
|
||||||
|
|
||||||
#define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS
|
#define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS
|
||||||
|
|
||||||
#define FOREACH_SLAB_TYPE(HANDLER, ...) HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__)
|
#define FOREACH_SLAB_TYPE(HANDLER, ...) \
|
||||||
|
HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \
|
||||||
|
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -33,7 +36,7 @@ enum KSlabType : u32 {
|
||||||
#undef DEFINE_SLAB_TYPE_ENUM_MEMBER
|
#undef DEFINE_SLAB_TYPE_ENUM_MEMBER
|
||||||
|
|
||||||
// Constexpr counts.
|
// Constexpr counts.
|
||||||
constexpr size_t SlabCountKProcess = 80;
|
constexpr size_t SlabCountProcess = 80;
|
||||||
constexpr size_t SlabCountKThread = 800;
|
constexpr size_t SlabCountKThread = 800;
|
||||||
constexpr size_t SlabCountKEvent = 700;
|
constexpr size_t SlabCountKEvent = 700;
|
||||||
constexpr size_t SlabCountKInterruptEvent = 100;
|
constexpr size_t SlabCountKInterruptEvent = 100;
|
||||||
|
@ -54,7 +57,7 @@ constexpr size_t SlabCountExtraKThread = 160;
|
||||||
|
|
||||||
// Global to hold our resource counts.
|
// Global to hold our resource counts.
|
||||||
KSlabResourceCounts g_slab_resource_counts = {
|
KSlabResourceCounts g_slab_resource_counts = {
|
||||||
.num_KProcess = SlabCountKProcess,
|
.num_Process = SlabCountProcess,
|
||||||
.num_KThread = SlabCountKThread,
|
.num_KThread = SlabCountKThread,
|
||||||
.num_KEvent = SlabCountKEvent,
|
.num_KEvent = SlabCountKEvent,
|
||||||
.num_KInterruptEvent = SlabCountKInterruptEvent,
|
.num_KInterruptEvent = SlabCountKInterruptEvent,
|
||||||
|
|
|
@ -15,7 +15,7 @@ class KMemoryLayout;
|
||||||
namespace Kernel::Init {
|
namespace Kernel::Init {
|
||||||
|
|
||||||
struct KSlabResourceCounts {
|
struct KSlabResourceCounts {
|
||||||
size_t num_KProcess;
|
size_t num_Process;
|
||||||
size_t num_KThread;
|
size_t num_KThread;
|
||||||
size_t num_KEvent;
|
size_t num_KEvent;
|
||||||
size_t num_KInterruptEvent;
|
size_t num_KInterruptEvent;
|
||||||
|
|
|
@ -53,10 +53,9 @@ private:
|
||||||
|
|
||||||
// Specialization of DynamicObjectCast for KSynchronizationObjects
|
// Specialization of DynamicObjectCast for KSynchronizationObjects
|
||||||
template <>
|
template <>
|
||||||
inline std::shared_ptr<KSynchronizationObject> DynamicObjectCast<KSynchronizationObject>(
|
inline KSynchronizationObject* DynamicObjectCast<KSynchronizationObject>(Object* object) {
|
||||||
std::shared_ptr<Object> object) {
|
|
||||||
if (object != nullptr && object->IsWaitable()) {
|
if (object != nullptr && object->IsWaitable()) {
|
||||||
return std::static_pointer_cast<KSynchronizationObject>(object);
|
return reinterpret_cast<KSynchronizationObject*>(object);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -614,7 +614,7 @@ struct KernelCore::Impl {
|
||||||
std::atomic<u64> next_thread_id{1};
|
std::atomic<u64> next_thread_id{1};
|
||||||
|
|
||||||
// Lists all processes that exist in the current session.
|
// Lists all processes that exist in the current session.
|
||||||
std::vector<std::shared_ptr<Process>> process_list;
|
std::vector<Process*> process_list;
|
||||||
Process* current_process = nullptr;
|
Process* current_process = nullptr;
|
||||||
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
|
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
|
||||||
Kernel::TimeManager time_manager;
|
Kernel::TimeManager time_manager;
|
||||||
|
@ -699,8 +699,8 @@ KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handl
|
||||||
return impl->global_handle_table.GetObject<KThread>(handle);
|
return impl->global_handle_table.GetObject<KThread>(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) {
|
void KernelCore::AppendNewProcess(Process* process) {
|
||||||
impl->process_list.push_back(std::move(process));
|
impl->process_list.push_back(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::MakeCurrentProcess(Process* process) {
|
void KernelCore::MakeCurrentProcess(Process* process) {
|
||||||
|
@ -715,7 +715,7 @@ const Process* KernelCore::CurrentProcess() const {
|
||||||
return impl->current_process;
|
return impl->current_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const {
|
const std::vector<Process*>& KernelCore::GetProcessList() const {
|
||||||
return impl->process_list;
|
return impl->process_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
|
KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
|
||||||
|
|
||||||
/// Adds the given shared pointer to an internal list of active processes.
|
/// Adds the given shared pointer to an internal list of active processes.
|
||||||
void AppendNewProcess(std::shared_ptr<Process> process);
|
void AppendNewProcess(Process* process);
|
||||||
|
|
||||||
/// Makes the given process the new current process.
|
/// Makes the given process the new current process.
|
||||||
void MakeCurrentProcess(Process* process);
|
void MakeCurrentProcess(Process* process);
|
||||||
|
@ -103,7 +103,7 @@ public:
|
||||||
const Process* CurrentProcess() const;
|
const Process* CurrentProcess() const;
|
||||||
|
|
||||||
/// Retrieves the list of processes.
|
/// Retrieves the list of processes.
|
||||||
const std::vector<std::shared_ptr<Process>>& GetProcessList() const;
|
const std::vector<Process*>& GetProcessList() const;
|
||||||
|
|
||||||
/// Gets the sole instance of the global scheduler
|
/// Gets the sole instance of the global scheduler
|
||||||
Kernel::GlobalSchedulerContext& GlobalSchedulerContext();
|
Kernel::GlobalSchedulerContext& GlobalSchedulerContext();
|
||||||
|
|
|
@ -86,9 +86,9 @@ std::shared_ptr<T> SharedFrom(T* raw) {
|
||||||
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
|
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline std::shared_ptr<T> DynamicObjectCast(std::shared_ptr<Object> object) {
|
inline T* DynamicObjectCast(Object* object) {
|
||||||
if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
|
if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
|
||||||
return std::static_pointer_cast<T>(object);
|
return reinterpret_cast<T*>(object);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ void SetupMainThread(Core::System& system, Process& owner_process, u32 priority,
|
||||||
// Register 1 must be a handle to the main thread
|
// Register 1 must be a handle to the main thread
|
||||||
Handle thread_handle{};
|
Handle thread_handle{};
|
||||||
owner_process.GetHandleTable().Add(&thread_handle, thread);
|
owner_process.GetHandleTable().Add(&thread_handle, thread);
|
||||||
|
|
||||||
|
thread->SetName("main");
|
||||||
thread->GetContext32().cpu_registers[0] = 0;
|
thread->GetContext32().cpu_registers[0] = 0;
|
||||||
thread->GetContext64().cpu_registers[0] = 0;
|
thread->GetContext64().cpu_registers[0] = 0;
|
||||||
thread->GetContext32().cpu_registers[1] = thread_handle;
|
thread->GetContext32().cpu_registers[1] = thread_handle;
|
||||||
|
@ -115,10 +117,10 @@ private:
|
||||||
std::bitset<num_slot_entries> is_slot_used;
|
std::bitset<num_slot_entries> is_slot_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) {
|
ResultCode Process::Initialize(Process* process, Core::System& system, std::string name,
|
||||||
|
ProcessType type) {
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
|
|
||||||
std::shared_ptr<Process> process = std::make_shared<Process>(system);
|
|
||||||
process->name = std::move(name);
|
process->name = std::move(name);
|
||||||
|
|
||||||
process->resource_limit = kernel.GetSystemResourceLimit();
|
process->resource_limit = kernel.GetSystemResourceLimit();
|
||||||
|
@ -127,6 +129,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
|
||||||
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
|
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
|
||||||
: kernel.CreateNewUserProcessID();
|
: kernel.CreateNewUserProcessID();
|
||||||
process->capabilities.InitializeForMetadatalessProcess();
|
process->capabilities.InitializeForMetadatalessProcess();
|
||||||
|
process->is_initialized = true;
|
||||||
|
|
||||||
std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr)));
|
std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr)));
|
||||||
std::uniform_int_distribution<u64> distribution;
|
std::uniform_int_distribution<u64> distribution;
|
||||||
|
@ -134,7 +137,8 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
|
||||||
[&] { return distribution(rng); });
|
[&] { return distribution(rng); });
|
||||||
|
|
||||||
kernel.AppendNewProcess(process);
|
kernel.AppendNewProcess(process);
|
||||||
return process;
|
|
||||||
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const {
|
std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const {
|
||||||
|
@ -332,7 +336,7 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
|
||||||
|
|
||||||
ChangeStatus(ProcessStatus::Running);
|
ChangeStatus(ProcessStatus::Running);
|
||||||
|
|
||||||
SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top);
|
SetupMainThread(kernel.System(), *this, main_thread_priority, main_thread_stack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::PrepareForTermination() {
|
void Process::PrepareForTermination() {
|
||||||
|
@ -354,7 +358,7 @@ void Process::PrepareForTermination() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
stop_threads(system.GlobalSchedulerContext().GetThreadList());
|
stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList());
|
||||||
|
|
||||||
FreeTLSRegion(tls_region_address);
|
FreeTLSRegion(tls_region_address);
|
||||||
tls_region_address = 0;
|
tls_region_address = 0;
|
||||||
|
@ -381,7 +385,7 @@ static auto FindTLSPageWithAvailableSlots(std::vector<TLSPage>& tls_pages) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VAddr Process::CreateTLSRegion() {
|
VAddr Process::CreateTLSRegion() {
|
||||||
KScopedSchedulerLock lock(system.Kernel());
|
KScopedSchedulerLock lock(kernel);
|
||||||
if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)};
|
if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)};
|
||||||
tls_page_iter != tls_pages.cend()) {
|
tls_page_iter != tls_pages.cend()) {
|
||||||
return *tls_page_iter->ReserveSlot();
|
return *tls_page_iter->ReserveSlot();
|
||||||
|
@ -392,7 +396,7 @@ VAddr Process::CreateTLSRegion() {
|
||||||
|
|
||||||
const VAddr start{page_table->GetKernelMapRegionStart()};
|
const VAddr start{page_table->GetKernelMapRegionStart()};
|
||||||
const VAddr size{page_table->GetKernelMapRegionEnd() - start};
|
const VAddr size{page_table->GetKernelMapRegionEnd() - start};
|
||||||
const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)};
|
const PAddr tls_map_addr{kernel.System().DeviceMemory().GetPhysicalAddr(tls_page_ptr)};
|
||||||
const VAddr tls_page_addr{page_table
|
const VAddr tls_page_addr{page_table
|
||||||
->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize,
|
->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize,
|
||||||
KMemoryState::ThreadLocal,
|
KMemoryState::ThreadLocal,
|
||||||
|
@ -412,7 +416,7 @@ VAddr Process::CreateTLSRegion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::FreeTLSRegion(VAddr tls_address) {
|
void Process::FreeTLSRegion(VAddr tls_address) {
|
||||||
KScopedSchedulerLock lock(system.Kernel());
|
KScopedSchedulerLock lock(kernel);
|
||||||
const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE);
|
const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE);
|
||||||
auto iter =
|
auto iter =
|
||||||
std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) {
|
std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) {
|
||||||
|
@ -433,7 +437,8 @@ void Process::LoadModule(CodeSet code_set, VAddr base_addr) {
|
||||||
page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission);
|
page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission);
|
||||||
};
|
};
|
||||||
|
|
||||||
system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size());
|
kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(),
|
||||||
|
code_set.memory.size());
|
||||||
|
|
||||||
ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute);
|
ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute);
|
||||||
ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read);
|
ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read);
|
||||||
|
@ -445,10 +450,10 @@ bool Process::IsSignaled() const {
|
||||||
return is_signaled;
|
return is_signaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::Process(Core::System& system)
|
Process::Process(KernelCore& kernel)
|
||||||
: KSynchronizationObject{system.Kernel()}, page_table{std::make_unique<KPageTable>(system)},
|
: KAutoObjectWithSlabHeapAndContainer{kernel},
|
||||||
handle_table{system.Kernel()}, address_arbiter{system}, condition_var{system},
|
page_table{std::make_unique<KPageTable>(kernel.System())}, handle_table{kernel},
|
||||||
state_lock{system.Kernel()}, system{system} {}
|
address_arbiter{kernel.System()}, condition_var{kernel.System()}, state_lock{kernel} {}
|
||||||
|
|
||||||
Process::~Process() = default;
|
Process::~Process() = default;
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,11 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/k_address_arbiter.h"
|
#include "core/hle/kernel/k_address_arbiter.h"
|
||||||
|
#include "core/hle/kernel/k_auto_object.h"
|
||||||
#include "core/hle/kernel/k_condition_variable.h"
|
#include "core/hle/kernel/k_condition_variable.h"
|
||||||
#include "core/hle/kernel/k_synchronization_object.h"
|
#include "core/hle/kernel/k_synchronization_object.h"
|
||||||
#include "core/hle/kernel/process_capability.h"
|
#include "core/hle/kernel/process_capability.h"
|
||||||
|
#include "core/hle/kernel/slab_helpers.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -60,9 +62,11 @@ enum class ProcessStatus {
|
||||||
DebugBreak,
|
DebugBreak,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Process final : public KSynchronizationObject {
|
class Process final : public KAutoObjectWithSlabHeapAndContainer<Process, KSynchronizationObject> {
|
||||||
|
KERNEL_AUTOOBJECT_TRAITS(Process, KSynchronizationObject);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Process(Core::System& system);
|
explicit Process(KernelCore& kernel);
|
||||||
~Process() override;
|
~Process() override;
|
||||||
|
|
||||||
enum : u64 {
|
enum : u64 {
|
||||||
|
@ -85,7 +89,7 @@ public:
|
||||||
|
|
||||||
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
||||||
|
|
||||||
static std::shared_ptr<Process> Create(Core::System& system, std::string name,
|
static ResultCode Initialize(Process* process, Core::System& system, std::string name,
|
||||||
ProcessType type);
|
ProcessType type);
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
|
@ -338,9 +342,21 @@ public:
|
||||||
|
|
||||||
void LoadModule(CodeSet code_set, VAddr base_addr);
|
void LoadModule(CodeSet code_set, VAddr base_addr);
|
||||||
|
|
||||||
bool IsSignaled() const override;
|
virtual bool IsInitialized() const override {
|
||||||
|
return is_initialized;
|
||||||
|
}
|
||||||
|
|
||||||
void Finalize() override {}
|
static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
|
||||||
|
|
||||||
|
virtual void Finalize() override {
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual u64 GetId() const override final {
|
||||||
|
return GetProcessID();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool IsSignaled() const override;
|
||||||
|
|
||||||
void PinCurrentThread();
|
void PinCurrentThread();
|
||||||
void UnpinCurrentThread();
|
void UnpinCurrentThread();
|
||||||
|
@ -462,6 +478,7 @@ private:
|
||||||
|
|
||||||
bool is_signaled{};
|
bool is_signaled{};
|
||||||
bool is_suspended{};
|
bool is_suspended{};
|
||||||
|
bool is_initialized{};
|
||||||
|
|
||||||
std::atomic<s32> num_created_threads{};
|
std::atomic<s32> num_created_threads{};
|
||||||
std::atomic<u16> num_threads{};
|
std::atomic<u16> num_threads{};
|
||||||
|
@ -474,9 +491,6 @@ private:
|
||||||
KThread* exception_thread{};
|
KThread* exception_thread{};
|
||||||
|
|
||||||
KLightLock state_lock;
|
KLightLock state_lock;
|
||||||
|
|
||||||
/// System context
|
|
||||||
Core::System& system;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -342,7 +342,7 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
|
||||||
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
||||||
std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle);
|
auto session = handle_table.Get<ClientSession>(handle);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
||||||
return ResultInvalidHandle;
|
return ResultInvalidHandle;
|
||||||
|
@ -437,7 +437,7 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha
|
||||||
{
|
{
|
||||||
auto object = handle_table.Get<KSynchronizationObject>(handle);
|
auto object = handle_table.Get<KSynchronizationObject>(handle);
|
||||||
if (object) {
|
if (object) {
|
||||||
objects[i] = object.get();
|
objects[i] = object;
|
||||||
succeeded = true;
|
succeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,7 +1190,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add
|
||||||
std::lock_guard lock{HLE::g_hle_lock};
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle);
|
auto process = handle_table.Get<Process>(process_handle);
|
||||||
if (!process) {
|
if (!process) {
|
||||||
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
|
||||||
process_handle);
|
process_handle);
|
||||||
|
|
|
@ -17,9 +17,8 @@ constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1};
|
||||||
|
|
||||||
constexpr u64 NO_PROCESS_FOUND_PID{0};
|
constexpr u64 NO_PROCESS_FOUND_PID{0};
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Kernel::Process>> SearchProcessList(
|
std::optional<Kernel::Process*> SearchProcessList(const std::vector<Kernel::Process*>& process_list,
|
||||||
const std::vector<std::shared_ptr<Kernel::Process>>& process_list,
|
std::function<bool(Kernel::Process*)> predicate) {
|
||||||
std::function<bool(const std::shared_ptr<Kernel::Process>&)> predicate) {
|
|
||||||
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
|
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
|
||||||
|
|
||||||
if (iter == process_list.end()) {
|
if (iter == process_list.end()) {
|
||||||
|
@ -30,7 +29,7 @@ std::optional<std::shared_ptr<Kernel::Process>> SearchProcessList(
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
|
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
|
||||||
const std::vector<std::shared_ptr<Kernel::Process>>& process_list) {
|
const std::vector<Kernel::Process*>& process_list) {
|
||||||
const auto process = SearchProcessList(process_list, [](const auto& process) {
|
const auto process = SearchProcessList(process_list, [](const auto& process) {
|
||||||
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
|
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
|
||||||
});
|
});
|
||||||
|
@ -125,8 +124,7 @@ private:
|
||||||
|
|
||||||
class Info final : public ServiceFramework<Info> {
|
class Info final : public ServiceFramework<Info> {
|
||||||
public:
|
public:
|
||||||
explicit Info(Core::System& system_,
|
explicit Info(Core::System& system_, const std::vector<Kernel::Process*>& process_list_)
|
||||||
const std::vector<std::shared_ptr<Kernel::Process>>& process_list_)
|
|
||||||
: ServiceFramework{system_, "pm:info"}, process_list{process_list_} {
|
: ServiceFramework{system_, "pm:info"}, process_list{process_list_} {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &Info::GetTitleId, "GetTitleId"},
|
{0, &Info::GetTitleId, "GetTitleId"},
|
||||||
|
@ -156,7 +154,7 @@ private:
|
||||||
rb.Push((*process)->GetTitleID());
|
rb.Push((*process)->GetTitleID());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<Kernel::Process>>& process_list;
|
const std::vector<Kernel::Process*>& process_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shell final : public ServiceFramework<Shell> {
|
class Shell final : public ServiceFramework<Shell> {
|
||||||
|
|
|
@ -118,7 +118,7 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa
|
||||||
: mutex_address(mutex_address) {
|
: mutex_address(mutex_address) {
|
||||||
mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address);
|
mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address);
|
||||||
owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask);
|
owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask);
|
||||||
owner = handle_table.Get<Kernel::KThread>(owner_handle);
|
owner = SharedFrom(handle_table.Get<Kernel::KThread>(owner_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;
|
WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;
|
||||||
|
|
Loading…
Reference in a new issue