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-14 20:06:02 -04:00
|
|
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-05-03 23:01:16 -04:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2018-08-03 14:42:28 -04:00
|
|
|
#include <array>
|
2015-06-21 10:44:11 -04:00
|
|
|
#include <cstddef>
|
2019-03-20 18:53:48 -04:00
|
|
|
#include <list>
|
2022-06-06 12:56:01 -04:00
|
|
|
#include <map>
|
2015-06-21 10:44:11 -04:00
|
|
|
#include <string>
|
2020-12-30 04:14:02 -05:00
|
|
|
#include "core/hle/kernel/k_address_arbiter.h"
|
2021-04-04 01:22:36 -04:00
|
|
|
#include "core/hle/kernel/k_auto_object.h"
|
2020-12-30 04:14:02 -05:00
|
|
|
#include "core/hle/kernel/k_condition_variable.h"
|
2021-04-24 05:40:31 -04:00
|
|
|
#include "core/hle/kernel/k_handle_table.h"
|
2022-10-02 17:26:30 -04:00
|
|
|
#include "core/hle/kernel/k_page_table.h"
|
2020-12-22 01:36:53 -05:00
|
|
|
#include "core/hle/kernel/k_synchronization_object.h"
|
2022-03-11 20:14:17 -05:00
|
|
|
#include "core/hle/kernel/k_thread_local_page.h"
|
2023-03-17 21:26:04 -04:00
|
|
|
#include "core/hle/kernel/k_typed_address.h"
|
2022-01-14 19:33:24 -05:00
|
|
|
#include "core/hle/kernel/k_worker_task.h"
|
2018-12-19 23:50:20 -05:00
|
|
|
#include "core/hle/kernel/process_capability.h"
|
2021-04-04 01:22:36 -04:00
|
|
|
#include "core/hle/kernel/slab_helpers.h"
|
2018-12-04 19:08:56 -05:00
|
|
|
#include "core/hle/result.h"
|
2015-05-03 23:01:16 -04:00
|
|
|
|
2019-03-07 18:48:14 -05:00
|
|
|
namespace Core {
|
2023-03-23 19:58:48 -04:00
|
|
|
namespace Memory {
|
|
|
|
class Memory;
|
|
|
|
};
|
|
|
|
|
2019-03-07 18:48:14 -05:00
|
|
|
class System;
|
2023-03-23 19:58:48 -04:00
|
|
|
} // namespace Core
|
2019-03-07 18:48:14 -05:00
|
|
|
|
2018-09-22 20:09:32 -04:00
|
|
|
namespace FileSys {
|
|
|
|
class ProgramMetadata;
|
|
|
|
}
|
|
|
|
|
2015-05-03 23:01:16 -04:00
|
|
|
namespace Kernel {
|
|
|
|
|
2018-08-28 12:30:33 -04:00
|
|
|
class KernelCore;
|
2021-01-30 04:40:49 -05:00
|
|
|
class KResourceLimit;
|
2020-12-31 02:01:08 -05:00
|
|
|
class KThread;
|
2021-09-25 11:01:53 -04:00
|
|
|
class KSharedMemoryInfo;
|
2019-06-05 14:32:33 -04:00
|
|
|
class TLSPage;
|
2018-08-28 12:30:33 -04:00
|
|
|
|
2019-03-20 12:40:09 -04:00
|
|
|
struct CodeSet;
|
|
|
|
|
2015-05-08 16:53:19 -04:00
|
|
|
enum class MemoryRegion : u16 {
|
2015-05-03 23:01:16 -04:00
|
|
|
APPLICATION = 1,
|
|
|
|
SYSTEM = 2,
|
|
|
|
BASE = 3,
|
|
|
|
};
|
|
|
|
|
2022-06-13 18:36:30 -04:00
|
|
|
enum class ProcessActivity : u32 {
|
|
|
|
Runnable,
|
|
|
|
Paused,
|
|
|
|
};
|
|
|
|
|
2022-06-06 12:56:01 -04: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-17 21:26:04 -04:00
|
|
|
KProcessAddress start_address;
|
|
|
|
KProcessAddress end_address;
|
2022-06-06 12:56:01 -04:00
|
|
|
DebugWatchpointType type;
|
|
|
|
};
|
|
|
|
|
2022-01-14 19:33:24 -05:00
|
|
|
class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> {
|
2021-04-24 01:04:28 -04:00
|
|
|
KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject);
|
2021-04-04 01:22:36 -04:00
|
|
|
|
2015-05-03 23:01:16 -04:00
|
|
|
public:
|
2023-03-07 10:49:41 -05:00
|
|
|
explicit KProcess(KernelCore& kernel);
|
2021-04-24 01:04:28 -04:00
|
|
|
~KProcess() override;
|
2019-11-24 20:15:51 -05:00
|
|
|
|
2022-09-05 20:47:00 -04:00
|
|
|
enum class State {
|
2022-10-18 22:13:20 -04: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-05 20:47:00 -04:00
|
|
|
};
|
|
|
|
|
2018-12-18 22:53:58 -05:00
|
|
|
enum : u64 {
|
|
|
|
/// Lowest allowed process ID for a kernel initial process.
|
|
|
|
InitialKIPIDMin = 1,
|
|
|
|
/// Highest allowed process ID for a kernel initial process.
|
|
|
|
InitialKIPIDMax = 80,
|
|
|
|
|
|
|
|
/// Lowest allowed process ID for a userland process.
|
|
|
|
ProcessIDMin = 81,
|
|
|
|
/// Highest allowed process ID for a userland process.
|
|
|
|
ProcessIDMax = 0xFFFFFFFFFFFFFFFF,
|
|
|
|
};
|
|
|
|
|
2019-06-10 00:28:33 -04:00
|
|
|
// Used to determine how process IDs are assigned.
|
|
|
|
enum class ProcessType {
|
|
|
|
KernelInternal,
|
|
|
|
Userland,
|
|
|
|
};
|
|
|
|
|
2018-11-13 12:25:43 -05:00
|
|
|
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
|
|
|
|
2022-06-25 23:44:19 -04:00
|
|
|
static Result Initialize(KProcess* process, Core::System& system, std::string process_name,
|
|
|
|
ProcessType type, KResourceLimit* res_limit);
|
2015-05-03 23:01:16 -04:00
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
/// Gets a reference to the process' page table.
|
|
|
|
KPageTable& GetPageTable() {
|
|
|
|
return m_page_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets const a reference to the process' page table.
|
|
|
|
const KPageTable& GetPageTable() const {
|
|
|
|
return m_page_table;
|
2018-09-29 18:47:00 -04:00
|
|
|
}
|
|
|
|
|
2018-10-20 14:34:41 -04:00
|
|
|
/// Gets a reference to the process' handle table.
|
2021-04-24 05:40:31 -04:00
|
|
|
KHandleTable& GetHandleTable() {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_handle_table;
|
2018-10-20 14:34:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets a const reference to the process' handle table.
|
2021-04-24 05:40:31 -04:00
|
|
|
const KHandleTable& GetHandleTable() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_handle_table;
|
2018-10-20 14:34:41 -04:00
|
|
|
}
|
|
|
|
|
2023-03-23 19:58:48 -04:00
|
|
|
/// Gets a reference to process's memory.
|
|
|
|
Core::Memory::Memory& GetMemory() const;
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
Result SignalToAddress(KProcessAddress address) {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_condition_var.SignalToAddress(address);
|
2019-03-07 18:48:14 -05:00
|
|
|
}
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
Result WaitForAddress(Handle handle, KProcessAddress address, u32 tag) {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_condition_var.WaitForAddress(handle, address, tag);
|
2019-03-07 18:48:14 -05:00
|
|
|
}
|
|
|
|
|
2020-12-30 04:14:02 -05:00
|
|
|
void SignalConditionVariable(u64 cv_key, int32_t count) {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_condition_var.Signal(cv_key, count);
|
2019-03-14 00:29:54 -04:00
|
|
|
}
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
Result WaitConditionVariable(KProcessAddress address, u64 cv_key, u32 tag, s64 ns) {
|
2023-03-07 16:45:13 -05:00
|
|
|
R_RETURN(m_condition_var.Wait(address, cv_key, tag, ns));
|
2020-12-30 04:14:02 -05:00
|
|
|
}
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
Result SignalAddressArbiter(uint64_t address, Svc::SignalType signal_type, s32 value,
|
|
|
|
s32 count) {
|
2023-03-07 16:45:13 -05:00
|
|
|
R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
|
2020-12-30 04:14:02 -05:00
|
|
|
}
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
Result WaitAddressArbiter(uint64_t address, Svc::ArbitrationType arb_type, s32 value,
|
2022-06-25 23:44:19 -04:00
|
|
|
s64 timeout) {
|
2023-03-07 16:45:13 -05:00
|
|
|
R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
|
2019-03-14 00:29:54 -04:00
|
|
|
}
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
KProcessAddress GetProcessLocalRegionAddress() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_plr_address;
|
2019-07-07 04:19:16 -04:00
|
|
|
}
|
|
|
|
|
2018-09-21 02:06:47 -04:00
|
|
|
/// Gets the current status of the process
|
2022-09-05 20:47:00 -04:00
|
|
|
State GetState() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_state;
|
2018-09-21 02:06:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets the unique ID that identifies this particular process.
|
2023-03-07 16:45:13 -05:00
|
|
|
u64 GetProcessId() const {
|
|
|
|
return m_process_id;
|
2018-09-21 02:06:47 -04:00
|
|
|
}
|
|
|
|
|
2021-11-03 14:15:51 -04:00
|
|
|
/// Gets the program ID corresponding to this process.
|
2023-03-07 16:45:13 -05:00
|
|
|
u64 GetProgramId() const {
|
|
|
|
return m_program_id;
|
2018-09-29 18:47:00 -04:00
|
|
|
}
|
|
|
|
|
2023-08-25 17:59:32 -04:00
|
|
|
KProcessAddress GetEntryPoint() const {
|
|
|
|
return m_code_address;
|
|
|
|
}
|
|
|
|
|
2018-09-29 18:47:00 -04:00
|
|
|
/// Gets the resource limit descriptor for this process
|
2021-04-21 00:28:11 -04:00
|
|
|
KResourceLimit* GetResourceLimit() const;
|
2018-09-29 18:47:00 -04:00
|
|
|
|
2018-12-27 21:14:59 -05:00
|
|
|
/// Gets the ideal CPU core ID for this process
|
2021-01-03 04:49:18 -05:00
|
|
|
u8 GetIdealCoreId() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_ideal_core;
|
2018-09-29 18:47:00 -04:00
|
|
|
}
|
|
|
|
|
2021-01-03 04:49:18 -05:00
|
|
|
/// Checks if the specified thread priority is valid.
|
|
|
|
bool CheckThreadPriority(s32 prio) const {
|
|
|
|
return ((1ULL << prio) & GetPriorityMask()) != 0;
|
|
|
|
}
|
|
|
|
|
2018-12-30 21:09:00 -05:00
|
|
|
/// Gets the bitmask of allowed cores that this process' threads can run on.
|
|
|
|
u64 GetCoreMask() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_capabilities.GetCoreMask();
|
2018-09-29 18:47:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets the bitmask of allowed thread priorities.
|
2018-12-30 21:09:00 -05:00
|
|
|
u64 GetPriorityMask() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_capabilities.GetPriorityMask();
|
2018-09-29 18:47:00 -04:00
|
|
|
}
|
|
|
|
|
2019-07-07 12:42:54 -04:00
|
|
|
/// Gets the amount of secure memory to allocate for memory management.
|
|
|
|
u32 GetSystemResourceSize() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_system_resource_size;
|
2018-09-29 18:47:00 -04:00
|
|
|
}
|
|
|
|
|
2019-07-07 14:48:11 -04:00
|
|
|
/// Gets the amount of secure memory currently in use for memory management.
|
|
|
|
u32 GetSystemResourceUsage() const {
|
|
|
|
// On hardware, this returns the amount of system resource memory that has
|
|
|
|
// been used by the kernel. This is problematic for Yuzu to emulate, because
|
|
|
|
// system resource memory is used for page tables -- and yuzu doesn't really
|
|
|
|
// have a way to calculate how much memory is required for page tables for
|
|
|
|
// the current process at any given time.
|
|
|
|
// TODO: Is this even worth implementing? Games may retrieve this value via
|
|
|
|
// an SDK function that gets used + available system resource size for debug
|
|
|
|
// or diagnostic purposes. However, it seems unlikely that a game would make
|
|
|
|
// decisions based on how much system memory is dedicated to its page tables.
|
|
|
|
// Is returning a value other than zero wise?
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-29 19:13:46 -04:00
|
|
|
/// Whether this process is an AArch64 or AArch32 process.
|
|
|
|
bool Is64BitProcess() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_is_64bit_process;
|
2018-09-29 19:13:46 -04:00
|
|
|
}
|
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
bool IsSuspended() const {
|
|
|
|
return m_is_suspended;
|
2021-01-20 16:42:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetSuspended(bool suspended) {
|
2023-03-07 16:45:13 -05:00
|
|
|
m_is_suspended = suspended;
|
2021-01-20 16:42:27 -05:00
|
|
|
}
|
|
|
|
|
2018-10-25 18:42:50 -04:00
|
|
|
/// Gets the total running time of the process instance in ticks.
|
|
|
|
u64 GetCPUTimeTicks() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_total_process_running_time_ticks;
|
2018-10-25 18:42:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Updates the total running time, adding the given ticks to it.
|
|
|
|
void UpdateCPUTimeTicks(u64 ticks) {
|
2023-03-07 16:45:13 -05:00
|
|
|
m_total_process_running_time_ticks += ticks;
|
2018-10-25 18:42:50 -04:00
|
|
|
}
|
|
|
|
|
2023-03-11 22:10:38 -05:00
|
|
|
/// Gets the process schedule count, used for thread yielding
|
2020-12-06 03:25:58 -05:00
|
|
|
s64 GetScheduledCount() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_schedule_count;
|
2020-11-28 14:54:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Increments the process schedule count, used for thread yielding.
|
2020-12-06 03:25:58 -05:00
|
|
|
void IncrementScheduledCount() {
|
2023-03-07 16:45:13 -05:00
|
|
|
++m_schedule_count;
|
2020-11-28 14:54:41 -05:00
|
|
|
}
|
|
|
|
|
2022-01-23 00:09:45 -05:00
|
|
|
void IncrementRunningThreadCount();
|
|
|
|
void DecrementRunningThreadCount();
|
2021-01-20 16:42:27 -05:00
|
|
|
|
|
|
|
void SetRunningThread(s32 core, KThread* thread, u64 idle_count) {
|
2023-03-07 16:45:13 -05:00
|
|
|
m_running_threads[core] = thread;
|
|
|
|
m_running_thread_idle_counts[core] = idle_count;
|
2021-01-20 16:42:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void ClearRunningThread(KThread* thread) {
|
2023-03-07 16:45:13 -05:00
|
|
|
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 16:42:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] KThread* GetRunningThread(s32 core) const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_running_threads[core];
|
2021-01-20 16:42:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ReleaseUserException(KThread* thread);
|
|
|
|
|
|
|
|
[[nodiscard]] KThread* GetPinnedThread(s32 core_id) const {
|
|
|
|
ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_pinned_threads[core_id];
|
2021-01-20 16:42:27 -05:00
|
|
|
}
|
|
|
|
|
2018-11-13 12:25:43 -05:00
|
|
|
/// Gets 8 bytes of random data for svcGetInfo RandomEntropy
|
|
|
|
u64 GetRandomEntropy(std::size_t index) const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_random_entropy.at(index);
|
2018-11-13 12:25:43 -05:00
|
|
|
}
|
|
|
|
|
2019-06-09 18:20:20 -04:00
|
|
|
/// Retrieves the total physical memory available to this process in bytes.
|
2022-10-02 17:26:30 -04:00
|
|
|
u64 GetTotalPhysicalMemoryAvailable();
|
2019-06-09 18:20:20 -04:00
|
|
|
|
|
|
|
/// Retrieves the total physical memory available to this process in bytes,
|
2019-07-07 14:48:11 -04:00
|
|
|
/// without the size of the personal system resource heap added to it.
|
2022-10-02 17:26:30 -04:00
|
|
|
u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource();
|
2019-06-09 18:20:20 -04:00
|
|
|
|
2019-03-28 22:59:17 -04:00
|
|
|
/// Retrieves the total physical memory used by this process in bytes.
|
2022-10-02 17:26:30 -04:00
|
|
|
u64 GetTotalPhysicalMemoryUsed();
|
2019-03-28 22:59:17 -04:00
|
|
|
|
2019-06-09 18:20:20 -04:00
|
|
|
/// Retrieves the total physical memory used by this process in bytes,
|
2019-07-07 14:48:11 -04:00
|
|
|
/// without the size of the personal system resource heap added to it.
|
2022-10-02 17:26:30 -04:00
|
|
|
u64 GetTotalPhysicalMemoryUsedWithoutSystemResource();
|
2019-06-09 18:20:20 -04:00
|
|
|
|
2019-03-20 18:53:48 -04:00
|
|
|
/// Gets the list of all threads created with this process as their owner.
|
2022-06-13 18:36:30 -04:00
|
|
|
std::list<KThread*>& GetThreadList() {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_thread_list;
|
2019-03-20 18:53:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Registers a thread as being created under this process,
|
|
|
|
/// adding it to this process' thread list.
|
2022-06-13 18:36:30 -04:00
|
|
|
void RegisterThread(KThread* thread);
|
2019-03-20 18:53:48 -04:00
|
|
|
|
|
|
|
/// Unregisters a thread from this process, removing it
|
|
|
|
/// from this process' thread list.
|
2022-06-13 18:36:30 -04:00
|
|
|
void UnregisterThread(KThread* thread);
|
2019-03-20 18:53:48 -04:00
|
|
|
|
2022-12-15 14:22:07 -05:00
|
|
|
/// Retrieves the number of available threads for this process.
|
|
|
|
u64 GetFreeThreadCount() const;
|
|
|
|
|
2018-12-04 19:08:56 -05:00
|
|
|
/// Clears the signaled state of the process if and only if it's signaled.
|
|
|
|
///
|
|
|
|
/// @pre The process must not be already terminated. If this is called on a
|
2023-03-06 19:04:12 -05:00
|
|
|
/// terminated process, then ResultInvalidState will be returned.
|
2018-12-04 19:08:56 -05:00
|
|
|
///
|
|
|
|
/// @pre The process must be in a signaled state. If this is called on a
|
2023-03-06 19:04:12 -05:00
|
|
|
/// process instance that is not signaled, ResultInvalidState will be
|
2018-12-04 19:08:56 -05:00
|
|
|
/// returned.
|
2022-06-25 23:44:19 -04:00
|
|
|
Result Reset();
|
2018-12-04 19:08:56 -05:00
|
|
|
|
2018-09-22 20:09:32 -04:00
|
|
|
/**
|
|
|
|
* Loads process-specifics configuration info with metadata provided
|
|
|
|
* by an executable.
|
|
|
|
*
|
2018-12-19 23:50:20 -05:00
|
|
|
* @param metadata The provided metadata to load process specific info from.
|
|
|
|
*
|
2021-05-21 01:05:04 -04:00
|
|
|
* @returns ResultSuccess if all relevant metadata was able to be
|
2018-12-19 23:50:20 -05:00
|
|
|
* loaded and parsed. Otherwise, an error code is returned.
|
2015-05-08 17:11:06 -04:00
|
|
|
*/
|
2023-09-14 14:34:05 -04:00
|
|
|
Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
|
|
|
|
bool is_hbl);
|
2015-05-08 17:11:06 -04:00
|
|
|
|
|
|
|
/**
|
2019-04-09 17:03:04 -04:00
|
|
|
* Starts the main application thread for this process.
|
|
|
|
*
|
|
|
|
* @param main_thread_priority The priority for the main thread.
|
|
|
|
* @param stack_size The stack size for the main thread in bytes.
|
2015-05-08 17:11:06 -04:00
|
|
|
*/
|
2019-04-09 17:03:04 -04:00
|
|
|
void Run(s32 main_thread_priority, u64 stack_size);
|
2015-05-03 23:01:16 -04:00
|
|
|
|
2018-09-21 02:06:47 -04:00
|
|
|
/**
|
|
|
|
* Prepares a process for termination by stopping all of its threads
|
|
|
|
* and clearing any other resources.
|
|
|
|
*/
|
|
|
|
void PrepareForTermination();
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
void LoadModule(CodeSet code_set, KProcessAddress base_addr);
|
2017-09-24 11:12:16 -04:00
|
|
|
|
2021-05-29 02:49:07 -04:00
|
|
|
bool IsInitialized() const override {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_is_initialized;
|
2021-04-04 01:22:36 -04:00
|
|
|
}
|
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
static void PostDestroy(uintptr_t arg) {}
|
2021-04-04 01:22:36 -04:00
|
|
|
|
2021-05-29 02:49:07 -04:00
|
|
|
void Finalize() override;
|
2021-04-04 01:22:36 -04:00
|
|
|
|
2021-05-29 02:49:07 -04:00
|
|
|
u64 GetId() const override {
|
2023-03-07 16:45:13 -05:00
|
|
|
return GetProcessId();
|
2021-04-04 01:22:36 -04:00
|
|
|
}
|
2020-12-22 01:36:53 -05:00
|
|
|
|
2023-09-14 14:34:05 -04:00
|
|
|
bool IsHbl() const {
|
|
|
|
return m_is_hbl;
|
|
|
|
}
|
|
|
|
|
2021-05-29 02:49:07 -04:00
|
|
|
bool IsSignaled() const override;
|
2021-01-16 03:25:29 -05:00
|
|
|
|
2022-01-14 19:33:24 -05:00
|
|
|
void DoWorkerTaskImpl();
|
|
|
|
|
2022-06-25 23:44:19 -04:00
|
|
|
Result SetActivity(ProcessActivity activity);
|
2022-06-13 18:36:30 -04:00
|
|
|
|
2021-12-30 00:40:38 -05:00
|
|
|
void PinCurrentThread(s32 core_id);
|
|
|
|
void UnpinCurrentThread(s32 core_id);
|
2021-11-11 02:02:45 -05:00
|
|
|
void UnpinThread(KThread* thread);
|
2021-01-20 16:42:27 -05:00
|
|
|
|
2021-01-25 01:54:37 -05:00
|
|
|
KLightLock& GetStateLock() {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_state_lock;
|
2021-01-25 01:54:37 -05:00
|
|
|
}
|
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
|
|
|
|
void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
|
2021-04-30 17:53:22 -04:00
|
|
|
|
2015-07-17 22:19:16 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
2018-12-27 18:31:31 -05:00
|
|
|
// Thread-local storage management
|
2015-07-17 22:19:16 -04:00
|
|
|
|
2018-09-21 01:26:29 -04:00
|
|
|
// Marks the next available region as used and returns the address of the slot.
|
2023-03-17 21:26:04 -04:00
|
|
|
[[nodiscard]] Result CreateThreadLocalRegion(KProcessAddress* out);
|
2018-09-21 01:26:29 -04:00
|
|
|
|
|
|
|
// Frees a used TLS slot identified by the given address
|
2023-03-17 21:26:04 -04:00
|
|
|
Result DeleteThreadLocalRegion(KProcessAddress addr);
|
2018-09-21 01:26:29 -04:00
|
|
|
|
2022-06-06 12:56:01 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Debug watchpoint management
|
|
|
|
|
|
|
|
// Attempts to insert a watchpoint into a free slot. Returns false if none are available.
|
2023-03-23 19:58:48 -04:00
|
|
|
bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
|
2022-06-06 12:56:01 -04:00
|
|
|
|
|
|
|
// Attempts to remove the watchpoint specified by the given parameters.
|
2023-03-23 19:58:48 -04:00
|
|
|
bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
|
2022-06-06 12:56:01 -04:00
|
|
|
|
|
|
|
const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const {
|
2023-03-07 16:45:13 -05:00
|
|
|
return m_watchpoints;
|
2022-06-06 12:56:01 -04:00
|
|
|
}
|
|
|
|
|
2023-03-06 20:34:25 -05:00
|
|
|
const std::string& GetName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2018-09-21 01:26:29 -04:00
|
|
|
private:
|
2021-01-20 16:42:27 -05: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);
|
2023-03-07 16:45:13 -05:00
|
|
|
ASSERT(m_pinned_threads[core_id] == nullptr);
|
|
|
|
m_pinned_threads[core_id] = thread;
|
2021-01-20 16:42:27 -05: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);
|
2023-03-07 16:45:13 -05:00
|
|
|
ASSERT(m_pinned_threads[core_id] == thread);
|
|
|
|
m_pinned_threads[core_id] = nullptr;
|
2021-01-20 16:42:27 -05:00
|
|
|
}
|
|
|
|
|
2022-10-15 01:55:51 -04:00
|
|
|
void FinalizeHandleTable() {
|
|
|
|
// Finalize the table.
|
2023-03-07 16:45:13 -05:00
|
|
|
m_handle_table.Finalize();
|
2022-10-15 01:55:51 -04:00
|
|
|
|
|
|
|
// Note that the table is finalized.
|
2023-03-07 16:45:13 -05:00
|
|
|
m_is_handle_table_initialized = false;
|
2022-10-15 01:55:51 -04:00
|
|
|
}
|
|
|
|
|
2022-09-05 20:47:00 -04:00
|
|
|
void ChangeState(State new_state);
|
2018-12-04 19:08:56 -05:00
|
|
|
|
2019-07-07 04:13:56 -04:00
|
|
|
/// Allocates the main thread stack for the process, given the stack size in bytes.
|
2022-06-25 23:44:19 -04:00
|
|
|
Result AllocateMainThreadStack(std::size_t stack_size);
|
2019-03-28 18:30:58 -04:00
|
|
|
|
2020-04-08 22:19:12 -04:00
|
|
|
/// Memory manager for this process
|
2023-03-07 16:45:13 -05:00
|
|
|
KPageTable m_page_table;
|
2019-03-28 18:52:45 -04:00
|
|
|
|
2018-09-21 02:06:47 -04:00
|
|
|
/// Current status of the process
|
2023-03-07 16:45:13 -05:00
|
|
|
State m_state{};
|
2018-09-21 02:06:47 -04:00
|
|
|
|
|
|
|
/// The ID of this process
|
2023-03-07 16:45:13 -05:00
|
|
|
u64 m_process_id = 0;
|
2018-09-21 02:06:47 -04:00
|
|
|
|
2018-09-29 18:47:00 -04:00
|
|
|
/// Title ID corresponding to the process
|
2023-03-07 16:45:13 -05:00
|
|
|
u64 m_program_id = 0;
|
2018-09-29 18:47:00 -04:00
|
|
|
|
2019-07-07 12:42:54 -04:00
|
|
|
/// Specifies additional memory to be reserved for the process's memory management by the
|
|
|
|
/// system. When this is non-zero, secure memory is allocated and used for page table allocation
|
|
|
|
/// instead of using the normal global page tables/memory block management.
|
2023-03-07 16:45:13 -05:00
|
|
|
u32 m_system_resource_size = 0;
|
2019-07-07 12:42:54 -04:00
|
|
|
|
2018-09-29 18:47:00 -04:00
|
|
|
/// Resource limit descriptor for this process
|
2023-03-07 16:45:13 -05:00
|
|
|
KResourceLimit* m_resource_limit{};
|
2018-09-29 18:47:00 -04:00
|
|
|
|
2023-03-17 21:26:04 -04:00
|
|
|
KVirtualAddress m_system_resource_address{};
|
2022-10-02 17:26:30 -04:00
|
|
|
|
2018-12-27 21:14:59 -05:00
|
|
|
/// The ideal CPU core for this process, threads are scheduled on this core by default.
|
2023-03-07 16:45:13 -05:00
|
|
|
u8 m_ideal_core = 0;
|
2018-09-29 18:47:00 -04:00
|
|
|
|
2018-12-19 23:50:20 -05:00
|
|
|
/// Contains the parsed process capability descriptors.
|
2023-03-07 16:45:13 -05:00
|
|
|
ProcessCapabilities m_capabilities;
|
2018-12-19 23:50:20 -05:00
|
|
|
|
2018-09-29 19:13:46 -04:00
|
|
|
/// Whether or not this process is AArch64, or AArch32.
|
|
|
|
/// By default, we currently assume this is true, unless otherwise
|
|
|
|
/// specified by metadata provided to the process during loading.
|
2023-03-07 16:45:13 -05:00
|
|
|
bool m_is_64bit_process = true;
|
2018-09-29 19:13:46 -04:00
|
|
|
|
2018-10-25 18:42:50 -04:00
|
|
|
/// Total running time for the process in ticks.
|
2023-03-07 16:45:13 -05:00
|
|
|
std::atomic<u64> m_total_process_running_time_ticks = 0;
|
2018-10-25 18:42:50 -04:00
|
|
|
|
2018-10-20 14:34:41 -04:00
|
|
|
/// Per-process handle table for storing created object handles in.
|
2023-03-07 16:45:13 -05:00
|
|
|
KHandleTable m_handle_table;
|
2018-10-20 14:34:41 -04:00
|
|
|
|
2019-03-07 18:48:14 -05:00
|
|
|
/// Per-process address arbiter.
|
2023-03-07 16:45:13 -05:00
|
|
|
KAddressArbiter m_address_arbiter;
|
2019-03-07 18:48:14 -05:00
|
|
|
|
2019-03-14 00:29:54 -04:00
|
|
|
/// The per-process mutex lock instance used for handling various
|
|
|
|
/// forms of services, such as lock arbitration, and condition
|
|
|
|
/// variable related facilities.
|
2023-03-07 16:45:13 -05:00
|
|
|
KConditionVariable m_condition_var;
|
2019-03-14 00:29:54 -04:00
|
|
|
|
2019-07-07 04:19:16 -04:00
|
|
|
/// Address indicating the location of the process' dedicated TLS region.
|
2023-03-17 21:26:04 -04:00
|
|
|
KProcessAddress m_plr_address = 0;
|
2019-07-07 04:19:16 -04:00
|
|
|
|
2023-08-25 17:59:32 -04:00
|
|
|
/// Address indicating the location of the process's entry point.
|
|
|
|
KProcessAddress m_code_address = 0;
|
|
|
|
|
2018-11-13 12:25:43 -05:00
|
|
|
/// Random values for svcGetInfo RandomEntropy
|
2023-03-07 16:45:13 -05:00
|
|
|
std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};
|
2018-11-13 12:25:43 -05:00
|
|
|
|
2019-03-20 18:53:48 -04:00
|
|
|
/// List of threads that are running with this process as their owner.
|
2023-03-07 16:45:13 -05:00
|
|
|
std::list<KThread*> m_thread_list;
|
2019-03-20 18:53:48 -04:00
|
|
|
|
2021-09-25 11:01:53 -04:00
|
|
|
/// List of shared memory that are running with this process as their owner.
|
2023-03-07 16:45:13 -05:00
|
|
|
std::list<KSharedMemoryInfo*> m_shared_memory_list;
|
2021-09-25 11:01:53 -04:00
|
|
|
|
2020-04-08 22:19:12 -04:00
|
|
|
/// Address of the top of the main thread's stack
|
2023-03-17 21:26:04 -04:00
|
|
|
KProcessAddress m_main_thread_stack_top{};
|
2020-04-08 22:19:12 -04:00
|
|
|
|
|
|
|
/// Size of the main thread's stack
|
2023-03-07 16:45:13 -05:00
|
|
|
std::size_t m_main_thread_stack_size{};
|
2020-04-08 22:19:12 -04:00
|
|
|
|
|
|
|
/// Memory usage capacity for the process
|
2023-03-07 16:45:13 -05:00
|
|
|
std::size_t m_memory_usage_capacity{};
|
2020-04-08 22:19:12 -04:00
|
|
|
|
|
|
|
/// Process total image size
|
2023-03-07 16:45:13 -05:00
|
|
|
std::size_t m_image_size{};
|
2020-07-15 13:23:12 -04:00
|
|
|
|
2020-11-28 14:54:41 -05:00
|
|
|
/// Schedule count of this process
|
2023-03-07 16:45:13 -05:00
|
|
|
s64 m_schedule_count{};
|
2020-11-28 14:54:41 -05:00
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
size_t m_memory_release_hint{};
|
2022-10-02 17:26:30 -04:00
|
|
|
|
2023-03-06 20:34:25 -05:00
|
|
|
std::string name{};
|
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
bool m_is_signaled{};
|
|
|
|
bool m_is_suspended{};
|
|
|
|
bool m_is_immortal{};
|
|
|
|
bool m_is_handle_table_initialized{};
|
|
|
|
bool m_is_initialized{};
|
2023-09-14 14:34:05 -04:00
|
|
|
bool m_is_hbl{};
|
2021-01-20 16:42:27 -05:00
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
std::atomic<u16> m_num_running_threads{};
|
2021-01-20 16:42:27 -05:00
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
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<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
|
|
|
|
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
2023-03-17 21:26:04 -04:00
|
|
|
std::map<KProcessAddress, u64> m_debug_page_refcounts;
|
2021-01-20 16:42:27 -05:00
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
KThread* m_exception_thread{};
|
2020-12-22 01:36:53 -05:00
|
|
|
|
2023-03-07 16:45:13 -05:00
|
|
|
KLightLock m_state_lock;
|
|
|
|
KLightLock m_list_lock;
|
2022-03-11 20:14:17 -05:00
|
|
|
|
|
|
|
using TLPTree =
|
|
|
|
Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
|
|
|
|
using TLPIterator = TLPTree::iterator;
|
2023-03-07 16:45:13 -05:00
|
|
|
TLPTree m_fully_used_tlp_tree;
|
|
|
|
TLPTree m_partially_used_tlp_tree;
|
2015-05-03 23:01:16 -04:00
|
|
|
};
|
|
|
|
|
2018-01-01 14:38:34 -05:00
|
|
|
} // namespace Kernel
|