2023-10-21 22:47:43 +02:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
chore: make yuzu REUSE compliant
[REUSE] is a specification that aims at making file copyright
information consistent, so that it can be both human and machine
readable. It basically requires that all files have a header containing
copyright and licensing information. When this isn't possible, like
when dealing with binary assets, generated files or embedded third-party
dependencies, it is permitted to insert copyright information in the
`.reuse/dep5` file.
Oh, and it also requires that all the licenses used in the project are
present in the `LICENSES` folder, that's why the diff is so huge.
This can be done automatically with `reuse download --all`.
The `reuse` tool also contains a handy subcommand that analyzes the
project and tells whether or not the project is (still) compliant,
`reuse lint`.
Following REUSE has a few advantages over the current approach:
- Copyright information is easy to access for users / downstream
- Files like `dist/license.md` do not need to exist anymore, as
`.reuse/dep5` is used instead
- `reuse lint` makes it easy to ensure that copyright information of
files like binary assets / images is always accurate and up to date
To add copyright information of files that didn't have it I looked up
who committed what and when, for each file. As yuzu contributors do not
have to sign a CLA or similar I couldn't assume that copyright ownership
was of the "yuzu Emulator Project", so I used the name and/or email of
the commit author instead.
[REUSE]: https://reuse.software
Follow-up to 01cf05bc75b1e47beb08937439f3ed9339e7b254
2022-05-15 02:06:02 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-05-04 05:01:16 +02:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-06-06 18:56:01 +02:00
|
|
|
#include <map>
|
2023-10-21 22:47:43 +02:00
|
|
|
|
2023-10-23 03:16:38 +02:00
|
|
|
#include "core/file_sys/program_metadata.h"
|
2023-10-21 22:47:43 +02:00
|
|
|
#include "core/hle/kernel/code_set.h"
|
2020-12-30 10:14:02 +01:00
|
|
|
#include "core/hle/kernel/k_address_arbiter.h"
|
2023-10-21 22:47:43 +02:00
|
|
|
#include "core/hle/kernel/k_capabilities.h"
|
2020-12-30 10:14:02 +01:00
|
|
|
#include "core/hle/kernel/k_condition_variable.h"
|
2021-04-24 11:40:31 +02:00
|
|
|
#include "core/hle/kernel/k_handle_table.h"
|
2023-10-21 22:47:43 +02:00
|
|
|
#include "core/hle/kernel/k_page_table_manager.h"
|
2023-10-23 03:16:38 +02:00
|
|
|
#include "core/hle/kernel/k_process_page_table.h"
|
2023-10-21 22:47:43 +02:00
|
|
|
#include "core/hle/kernel/k_system_resource.h"
|
|
|
|
#include "core/hle/kernel/k_thread.h"
|
2022-03-12 02:14:17 +01:00
|
|
|
#include "core/hle/kernel/k_thread_local_page.h"
|
2018-09-23 02:09:32 +02:00
|
|
|
|
2015-05-04 05:01:16 +02:00
|
|
|
namespace Kernel {
|
|
|
|
|
2022-06-06 18:56:01 +02:00
|
|
|
enum class DebugWatchpointType : u8 {
|
|
|
|
None = 0,
|
|
|
|
Read = 1 << 0,
|
|
|
|
Write = 1 << 1,
|
|
|
|
ReadOrWrite = Read | Write,
|
|
|
|
};
|
|
|
|
DECLARE_ENUM_FLAG_OPERATORS(DebugWatchpointType);
|
|
|
|
|
|
|
|
struct DebugWatchpoint {
|
2023-03-18 02:26:04 +01:00
|
|
|
KProcessAddress start_address;
|
|
|
|
KProcessAddress end_address;
|
2022-06-06 18:56:01 +02:00
|
|
|
DebugWatchpointType type;
|
|
|
|
};
|
|
|
|
|
2022-01-15 01:33:24 +01:00
|
|
|
class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> {
|
2021-04-24 07:04:28 +02:00
|
|
|
KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject);
|
2021-04-04 07:22:36 +02:00
|
|
|
|
2015-05-04 05:01:16 +02:00
|
|
|
public:
|
2022-09-06 02:47:00 +02:00
|
|
|
enum class State {
|
2022-10-19 04:13:20 +02:00
|
|
|
Created = static_cast<u32>(Svc::ProcessState::Created),
|
|
|
|
CreatedAttached = static_cast<u32>(Svc::ProcessState::CreatedAttached),
|
|
|
|
Running = static_cast<u32>(Svc::ProcessState::Running),
|
|
|
|
Crashed = static_cast<u32>(Svc::ProcessState::Crashed),
|
|
|
|
RunningAttached = static_cast<u32>(Svc::ProcessState::RunningAttached),
|
|
|
|
Terminating = static_cast<u32>(Svc::ProcessState::Terminating),
|
|
|
|
Terminated = static_cast<u32>(Svc::ProcessState::Terminated),
|
|
|
|
DebugBreak = static_cast<u32>(Svc::ProcessState::DebugBreak),
|
2022-09-06 02:47:00 +02:00
|
|
|
};
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
using ThreadList = Common::IntrusiveListMemberTraits<&KThread::m_process_list_node>::ListType;
|
2018-12-19 04:53:58 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
static constexpr size_t AslrAlignment = 2_MiB;
|
2019-06-10 06:28:33 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
public:
|
|
|
|
static constexpr u64 InitialProcessIdMin = 1;
|
|
|
|
static constexpr u64 InitialProcessIdMax = 0x50;
|
2018-11-13 18:25:43 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
static constexpr u64 ProcessIdMin = InitialProcessIdMax + 1;
|
|
|
|
static constexpr u64 ProcessIdMax = std::numeric_limits<u64>::max();
|
2015-05-04 05:01:16 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
private:
|
|
|
|
using SharedMemoryInfoList = Common::IntrusiveListBaseTraits<KSharedMemoryInfo>::ListType;
|
|
|
|
using TLPTree =
|
|
|
|
Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
|
|
|
|
using TLPIterator = TLPTree::iterator;
|
2023-03-07 22:45:13 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
private:
|
2023-10-23 03:16:38 +02:00
|
|
|
KProcessPageTable m_page_table;
|
2023-10-21 22:47:43 +02:00
|
|
|
std::atomic<size_t> m_used_kernel_memory_size{};
|
|
|
|
TLPTree m_fully_used_tlp_tree{};
|
|
|
|
TLPTree m_partially_used_tlp_tree{};
|
|
|
|
s32 m_ideal_core_id{};
|
|
|
|
KResourceLimit* m_resource_limit{};
|
|
|
|
KSystemResource* m_system_resource{};
|
|
|
|
size_t m_memory_release_hint{};
|
|
|
|
State m_state{};
|
|
|
|
KLightLock m_state_lock;
|
|
|
|
KLightLock m_list_lock;
|
|
|
|
KConditionVariable m_cond_var;
|
|
|
|
KAddressArbiter m_address_arbiter;
|
|
|
|
std::array<u64, 4> m_entropy{};
|
|
|
|
bool m_is_signaled{};
|
|
|
|
bool m_is_initialized{};
|
|
|
|
bool m_is_application{};
|
|
|
|
bool m_is_default_application_system_resource{};
|
|
|
|
bool m_is_hbl{};
|
|
|
|
std::array<char, 13> m_name{};
|
|
|
|
std::atomic<u16> m_num_running_threads{};
|
|
|
|
Svc::CreateProcessFlag m_flags{};
|
|
|
|
KMemoryManager::Pool m_memory_pool{};
|
|
|
|
s64 m_schedule_count{};
|
|
|
|
KCapabilities m_capabilities{};
|
|
|
|
u64 m_program_id{};
|
|
|
|
u64 m_process_id{};
|
|
|
|
KProcessAddress m_code_address{};
|
|
|
|
size_t m_code_size{};
|
|
|
|
size_t m_main_thread_stack_size{};
|
|
|
|
size_t m_max_process_memory{};
|
|
|
|
u32 m_version{};
|
|
|
|
KHandleTable m_handle_table;
|
|
|
|
KProcessAddress m_plr_address{};
|
|
|
|
KThread* m_exception_thread{};
|
|
|
|
ThreadList m_thread_list{};
|
|
|
|
SharedMemoryInfoList m_shared_memory_list{};
|
|
|
|
bool m_is_suspended{};
|
|
|
|
bool m_is_immortal{};
|
|
|
|
bool m_is_handle_table_initialized{};
|
|
|
|
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_running_threads{};
|
|
|
|
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{};
|
|
|
|
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_switch_counts{};
|
|
|
|
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
|
|
|
|
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
|
|
|
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
|
|
|
|
std::atomic<s64> m_cpu_time{};
|
|
|
|
std::atomic<s64> m_num_process_switches{};
|
|
|
|
std::atomic<s64> m_num_thread_switches{};
|
|
|
|
std::atomic<s64> m_num_fpu_switches{};
|
|
|
|
std::atomic<s64> m_num_supervisor_calls{};
|
|
|
|
std::atomic<s64> m_num_ipc_messages{};
|
|
|
|
std::atomic<s64> m_num_ipc_replies{};
|
|
|
|
std::atomic<s64> m_num_ipc_receives{};
|
2023-11-20 14:52:18 +01:00
|
|
|
#ifdef HAS_NCE
|
|
|
|
std::unordered_map<u64, u64> m_post_handlers{};
|
|
|
|
#endif
|
2018-09-30 00:47:00 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
private:
|
|
|
|
Result StartTermination();
|
|
|
|
void FinishTermination();
|
2018-10-20 20:34:41 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void PinThread(s32 core_id, KThread* thread) {
|
|
|
|
ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
|
|
|
|
ASSERT(thread != nullptr);
|
|
|
|
ASSERT(m_pinned_threads[core_id] == nullptr);
|
|
|
|
m_pinned_threads[core_id] = thread;
|
2018-10-20 20:34:41 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void UnpinThread(s32 core_id, KThread* thread) {
|
|
|
|
ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
|
|
|
|
ASSERT(thread != nullptr);
|
|
|
|
ASSERT(m_pinned_threads[core_id] == thread);
|
|
|
|
m_pinned_threads[core_id] = nullptr;
|
2019-03-08 00:48:14 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
public:
|
|
|
|
explicit KProcess(KernelCore& kernel);
|
|
|
|
~KProcess() override;
|
2019-03-08 00:48:14 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result Initialize(const Svc::CreateProcessParameter& params, KResourceLimit* res_limit,
|
|
|
|
bool is_real);
|
2019-03-14 05:29:54 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result Initialize(const Svc::CreateProcessParameter& params, const KPageGroup& pg,
|
|
|
|
std::span<const u32> caps, KResourceLimit* res_limit,
|
|
|
|
KMemoryManager::Pool pool, bool immortal);
|
|
|
|
Result Initialize(const Svc::CreateProcessParameter& params, std::span<const u32> user_caps,
|
2023-11-17 20:58:29 +01:00
|
|
|
KResourceLimit* res_limit, KMemoryManager::Pool pool,
|
|
|
|
KProcessAddress aslr_space_start);
|
2023-10-21 22:47:43 +02:00
|
|
|
void Exit();
|
2020-12-30 10:14:02 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
const char* GetName() const {
|
|
|
|
return m_name.data();
|
2020-12-30 10:14:02 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
u64 GetProgramId() const {
|
|
|
|
return m_program_id;
|
2019-03-14 05:29:54 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
u64 GetProcessId() const {
|
|
|
|
return m_process_id;
|
2019-07-07 10:19:16 +02:00
|
|
|
}
|
|
|
|
|
2022-09-06 02:47:00 +02:00
|
|
|
State GetState() const {
|
2023-03-07 22:45:13 +01:00
|
|
|
return m_state;
|
2018-09-21 08:06:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
u64 GetCoreMask() const {
|
|
|
|
return m_capabilities.GetCoreMask();
|
|
|
|
}
|
|
|
|
u64 GetPhysicalCoreMask() const {
|
|
|
|
return m_capabilities.GetPhysicalCoreMask();
|
|
|
|
}
|
|
|
|
u64 GetPriorityMask() const {
|
|
|
|
return m_capabilities.GetPriorityMask();
|
2018-09-21 08:06:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
s32 GetIdealCoreId() const {
|
|
|
|
return m_ideal_core_id;
|
|
|
|
}
|
|
|
|
void SetIdealCoreId(s32 core_id) {
|
|
|
|
m_ideal_core_id = core_id;
|
2018-09-30 00:47:00 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool CheckThreadPriority(s32 prio) const {
|
|
|
|
return ((1ULL << prio) & this->GetPriorityMask()) != 0;
|
2023-08-25 23:59:32 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
u32 GetCreateProcessFlags() const {
|
|
|
|
return static_cast<u32>(m_flags);
|
|
|
|
}
|
2018-09-30 00:47:00 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool Is64Bit() const {
|
|
|
|
return True(m_flags & Svc::CreateProcessFlag::Is64Bit);
|
2018-09-30 00:47:00 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KProcessAddress GetEntryPoint() const {
|
|
|
|
return m_code_address;
|
2021-01-03 10:49:18 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
size_t GetMainStackSize() const {
|
|
|
|
return m_main_thread_stack_size;
|
2018-09-30 00:47:00 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KMemoryManager::Pool GetMemoryPool() const {
|
|
|
|
return m_memory_pool;
|
2018-09-30 00:47:00 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
u64 GetRandomEntropy(size_t i) const {
|
|
|
|
return m_entropy[i];
|
2018-09-30 00:47:00 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool IsApplication() const {
|
|
|
|
return m_is_application;
|
2019-07-07 20:48:11 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool IsDefaultApplicationSystemResource() const {
|
|
|
|
return m_is_default_application_system_resource;
|
2018-09-30 01:13:46 +02:00
|
|
|
}
|
|
|
|
|
2023-03-07 22:45:13 +01:00
|
|
|
bool IsSuspended() const {
|
|
|
|
return m_is_suspended;
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
void SetSuspended(bool suspended) {
|
2023-03-07 22:45:13 +01:00
|
|
|
m_is_suspended = suspended;
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result Terminate();
|
|
|
|
|
|
|
|
bool IsTerminated() const {
|
|
|
|
return m_state == State::Terminated;
|
2018-10-26 00:42:50 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool IsPermittedSvc(u32 svc_id) const {
|
|
|
|
return m_capabilities.IsPermittedSvc(svc_id);
|
2018-10-26 00:42:50 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool IsPermittedInterrupt(s32 interrupt_id) const {
|
|
|
|
return m_capabilities.IsPermittedInterrupt(interrupt_id);
|
2020-11-28 20:54:41 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool IsPermittedDebug() const {
|
|
|
|
return m_capabilities.IsPermittedDebug();
|
2020-11-28 20:54:41 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool CanForceDebug() const {
|
|
|
|
return m_capabilities.CanForceDebug();
|
|
|
|
}
|
2021-01-20 22:42:27 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool IsHbl() const {
|
|
|
|
return m_is_hbl;
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-23 03:16:38 +02:00
|
|
|
u32 GetAllocateOption() const {
|
|
|
|
return m_page_table.GetAllocateOption();
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
ThreadList& GetThreadList() {
|
|
|
|
return m_thread_list;
|
|
|
|
}
|
|
|
|
const ThreadList& GetThreadList() const {
|
|
|
|
return m_thread_list;
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool EnterUserException();
|
|
|
|
bool LeaveUserException();
|
2021-01-20 22:42:27 +01:00
|
|
|
bool ReleaseUserException(KThread* thread);
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KThread* GetPinnedThread(s32 core_id) const {
|
2021-01-20 22:42:27 +01:00
|
|
|
ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
|
2023-03-07 22:45:13 +01:00
|
|
|
return m_pinned_threads[core_id];
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
const Svc::SvcAccessFlagSet& GetSvcPermissions() const {
|
|
|
|
return m_capabilities.GetSvcPermissions();
|
2018-11-13 18:25:43 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KResourceLimit* GetResourceLimit() const {
|
|
|
|
return m_resource_limit;
|
2019-03-20 23:53:48 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
bool ReserveResource(Svc::LimitableResource which, s64 value);
|
|
|
|
bool ReserveResource(Svc::LimitableResource which, s64 value, s64 timeout);
|
|
|
|
void ReleaseResource(Svc::LimitableResource which, s64 value);
|
|
|
|
void ReleaseResource(Svc::LimitableResource which, s64 value, s64 hint);
|
2019-03-20 23:53:48 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KLightLock& GetStateLock() {
|
|
|
|
return m_state_lock;
|
|
|
|
}
|
|
|
|
KLightLock& GetListLock() {
|
|
|
|
return m_list_lock;
|
|
|
|
}
|
2019-03-20 23:53:48 +01:00
|
|
|
|
2023-10-23 03:16:38 +02:00
|
|
|
KProcessPageTable& GetPageTable() {
|
2023-10-21 22:47:43 +02:00
|
|
|
return m_page_table;
|
|
|
|
}
|
2023-10-23 03:16:38 +02:00
|
|
|
const KProcessPageTable& GetPageTable() const {
|
2023-10-21 22:47:43 +02:00
|
|
|
return m_page_table;
|
|
|
|
}
|
2018-12-05 01:08:56 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KHandleTable& GetHandleTable() {
|
|
|
|
return m_handle_table;
|
|
|
|
}
|
|
|
|
const KHandleTable& GetHandleTable() const {
|
|
|
|
return m_handle_table;
|
|
|
|
}
|
2015-05-08 23:11:06 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
size_t GetUsedUserPhysicalMemorySize() const;
|
|
|
|
size_t GetTotalUserPhysicalMemorySize() const;
|
|
|
|
size_t GetUsedNonSystemUserPhysicalMemorySize() const;
|
|
|
|
size_t GetTotalNonSystemUserPhysicalMemorySize() const;
|
2015-05-04 05:01:16 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
|
|
|
|
void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
|
2018-09-21 08:06:47 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result CreateThreadLocalRegion(KProcessAddress* out);
|
|
|
|
Result DeleteThreadLocalRegion(KProcessAddress addr);
|
2017-09-24 17:12:16 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KProcessAddress GetProcessLocalRegionAddress() const {
|
|
|
|
return m_plr_address;
|
2021-04-04 07:22:36 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KThread* GetExceptionThread() const {
|
|
|
|
return m_exception_thread;
|
2021-04-04 07:22:36 +02:00
|
|
|
}
|
2020-12-22 07:36:53 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void AddCpuTime(s64 diff) {
|
|
|
|
m_cpu_time += diff;
|
|
|
|
}
|
|
|
|
s64 GetCpuTime() {
|
|
|
|
return m_cpu_time.load();
|
2023-09-14 20:34:05 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
s64 GetScheduledCount() const {
|
|
|
|
return m_schedule_count;
|
|
|
|
}
|
|
|
|
void IncrementScheduledCount() {
|
|
|
|
++m_schedule_count;
|
|
|
|
}
|
2022-01-15 01:33:24 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void IncrementRunningThreadCount();
|
|
|
|
void DecrementRunningThreadCount();
|
2022-06-14 00:36:30 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
size_t GetRequiredSecureMemorySizeNonDefault() const {
|
|
|
|
if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) {
|
|
|
|
auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
|
|
|
|
return secure_system_resource->CalculateRequiredSecureMemorySize();
|
|
|
|
}
|
2021-01-20 22:42:27 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
return 0;
|
2021-01-25 07:54:37 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
size_t GetRequiredSecureMemorySize() const {
|
|
|
|
if (m_system_resource->IsSecureResource()) {
|
|
|
|
auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
|
|
|
|
return secure_system_resource->CalculateRequiredSecureMemorySize();
|
|
|
|
}
|
2018-09-21 07:26:29 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2018-09-21 07:26:29 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
size_t GetTotalSystemResourceSize() const {
|
|
|
|
if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) {
|
|
|
|
auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
|
|
|
|
return secure_system_resource->GetSize();
|
|
|
|
}
|
2022-06-06 18:56:01 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2022-06-06 18:56:01 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
size_t GetUsedSystemResourceSize() const {
|
|
|
|
if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) {
|
|
|
|
auto* secure_system_resource = static_cast<KSecureSystemResource*>(m_system_resource);
|
|
|
|
return secure_system_resource->GetUsedSize();
|
|
|
|
}
|
2022-06-06 18:56:01 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
return 0;
|
2022-06-06 18:56:01 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void SetRunningThread(s32 core, KThread* thread, u64 idle_count, u64 switch_count) {
|
|
|
|
m_running_threads[core] = thread;
|
|
|
|
m_running_thread_idle_counts[core] = idle_count;
|
|
|
|
m_running_thread_switch_counts[core] = switch_count;
|
2023-03-07 02:34:25 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void ClearRunningThread(KThread* thread) {
|
|
|
|
for (size_t i = 0; i < m_running_threads.size(); ++i) {
|
|
|
|
if (m_running_threads[i] == thread) {
|
|
|
|
m_running_threads[i] = nullptr;
|
|
|
|
}
|
|
|
|
}
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
const KSystemResource& GetSystemResource() const {
|
|
|
|
return *m_system_resource;
|
2021-01-20 22:42:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
const KMemoryBlockSlabManager& GetMemoryBlockSlabManager() const {
|
|
|
|
return m_system_resource->GetMemoryBlockSlabManager();
|
|
|
|
}
|
|
|
|
const KBlockInfoManager& GetBlockInfoManager() const {
|
|
|
|
return m_system_resource->GetBlockInfoManager();
|
|
|
|
}
|
|
|
|
const KPageTableManager& GetPageTableManager() const {
|
|
|
|
return m_system_resource->GetPageTableManager();
|
2022-10-15 07:55:51 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
KThread* GetRunningThread(s32 core) const {
|
|
|
|
return m_running_threads[core];
|
|
|
|
}
|
|
|
|
u64 GetRunningThreadIdleCount(s32 core) const {
|
|
|
|
return m_running_thread_idle_counts[core];
|
|
|
|
}
|
|
|
|
u64 GetRunningThreadSwitchCount(s32 core) const {
|
|
|
|
return m_running_thread_switch_counts[core];
|
|
|
|
}
|
2018-09-21 08:06:47 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void RegisterThread(KThread* thread);
|
|
|
|
void UnregisterThread(KThread* thread);
|
2018-09-21 08:06:47 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result Run(s32 priority, size_t stack_size);
|
2018-09-30 00:47:00 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result Reset();
|
2019-07-07 18:42:54 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void SetDebugBreak() {
|
|
|
|
if (m_state == State::RunningAttached) {
|
|
|
|
this->ChangeState(State::DebugBreak);
|
|
|
|
}
|
|
|
|
}
|
2018-09-30 00:47:00 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void SetAttached() {
|
|
|
|
if (m_state == State::DebugBreak) {
|
|
|
|
this->ChangeState(State::RunningAttached);
|
|
|
|
}
|
|
|
|
}
|
2022-10-02 23:26:30 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result SetActivity(Svc::ProcessActivity activity);
|
2018-09-30 00:47:00 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void PinCurrentThread();
|
|
|
|
void UnpinCurrentThread();
|
|
|
|
void UnpinThread(KThread* thread);
|
2018-12-20 05:50:20 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void SignalConditionVariable(uintptr_t cv_key, int32_t count) {
|
|
|
|
return m_cond_var.Signal(cv_key, count);
|
|
|
|
}
|
2018-09-30 01:13:46 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result WaitConditionVariable(KProcessAddress address, uintptr_t cv_key, u32 tag, s64 ns) {
|
|
|
|
R_RETURN(m_cond_var.Wait(address, cv_key, tag, ns));
|
|
|
|
}
|
2018-10-26 00:42:50 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result SignalAddressArbiter(uintptr_t address, Svc::SignalType signal_type, s32 value,
|
|
|
|
s32 count) {
|
|
|
|
R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
|
|
|
|
}
|
2018-10-20 20:34:41 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result WaitAddressArbiter(uintptr_t address, Svc::ArbitrationType arb_type, s32 value,
|
|
|
|
s64 timeout) {
|
|
|
|
R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
|
|
|
|
}
|
2019-03-08 00:48:14 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids, s32 max_out_count);
|
2019-03-14 05:29:54 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
static void Switch(KProcess* cur_process, KProcess* next_process);
|
2019-07-07 10:19:16 +02:00
|
|
|
|
2023-11-20 14:52:18 +01:00
|
|
|
#ifdef HAS_NCE
|
2023-11-17 22:44:53 +01:00
|
|
|
std::unordered_map<u64, u64>& GetPostHandlers() noexcept {
|
|
|
|
return m_post_handlers;
|
|
|
|
}
|
2023-11-20 14:52:18 +01:00
|
|
|
#endif
|
2023-11-17 22:44:53 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
public:
|
|
|
|
// Attempts to insert a watchpoint into a free slot. Returns false if none are available.
|
|
|
|
bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
|
2023-08-25 23:59:32 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
// Attempts to remove the watchpoint specified by the given parameters.
|
|
|
|
bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
|
2018-11-13 18:25:43 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const {
|
|
|
|
return m_watchpoints;
|
|
|
|
}
|
2019-03-20 23:53:48 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
public:
|
|
|
|
Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
|
2023-11-17 20:58:29 +01:00
|
|
|
KProcessAddress aslr_space_start, bool is_hbl);
|
2021-09-25 17:01:53 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void LoadModule(CodeSet code_set, KProcessAddress base_addr);
|
2020-04-09 04:19:12 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Core::Memory::Memory& GetMemory() const;
|
2020-04-09 04:19:12 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
public:
|
|
|
|
// Overridden parent functions.
|
|
|
|
bool IsInitialized() const override {
|
|
|
|
return m_is_initialized;
|
|
|
|
}
|
2020-04-09 04:19:12 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
static void PostDestroy(uintptr_t arg) {}
|
2020-07-15 19:23:12 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void Finalize() override;
|
2020-11-28 20:54:41 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
u64 GetIdImpl() const {
|
|
|
|
return this->GetProcessId();
|
|
|
|
}
|
|
|
|
u64 GetId() const override {
|
|
|
|
return this->GetIdImpl();
|
|
|
|
}
|
2022-10-02 23:26:30 +02:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
virtual bool IsSignaled() const override {
|
|
|
|
ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
|
|
|
|
return m_is_signaled;
|
|
|
|
}
|
2023-03-07 02:34:25 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void DoWorkerTaskImpl();
|
2021-01-20 22:42:27 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
private:
|
|
|
|
void ChangeState(State new_state) {
|
|
|
|
if (m_state != new_state) {
|
|
|
|
m_state = new_state;
|
|
|
|
m_is_signaled = true;
|
|
|
|
this->NotifyAvailable();
|
|
|
|
}
|
|
|
|
}
|
2021-01-20 22:42:27 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
Result InitializeHandleTable(s32 size) {
|
|
|
|
// Try to initialize the handle table.
|
|
|
|
R_TRY(m_handle_table.Initialize(size));
|
2021-01-20 22:42:27 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
// We succeeded, so note that we did.
|
|
|
|
m_is_handle_table_initialized = true;
|
|
|
|
R_SUCCEED();
|
|
|
|
}
|
2020-12-22 07:36:53 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
void FinalizeHandleTable() {
|
|
|
|
// Finalize the table.
|
|
|
|
m_handle_table.Finalize();
|
2022-03-12 02:14:17 +01:00
|
|
|
|
2023-10-21 22:47:43 +02:00
|
|
|
// Note that the table is finalized.
|
|
|
|
m_is_handle_table_initialized = false;
|
|
|
|
}
|
2015-05-04 05:01:16 +02:00
|
|
|
};
|
|
|
|
|
2018-01-01 20:38:34 +01:00
|
|
|
} // namespace Kernel
|