process.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <bitset>
  7. #include <cstddef>
  8. #include <string>
  9. #include <vector>
  10. #include <boost/container/static_vector.hpp>
  11. #include "common/common_types.h"
  12. #include "core/hle/kernel/address_arbiter.h"
  13. #include "core/hle/kernel/handle_table.h"
  14. #include "core/hle/kernel/mutex.h"
  15. #include "core/hle/kernel/process_capability.h"
  16. #include "core/hle/kernel/vm_manager.h"
  17. #include "core/hle/kernel/wait_object.h"
  18. #include "core/hle/result.h"
  19. namespace Core {
  20. class System;
  21. }
  22. namespace FileSys {
  23. class ProgramMetadata;
  24. }
  25. namespace Kernel {
  26. class KernelCore;
  27. class ResourceLimit;
  28. class Thread;
  29. struct CodeSet;
  30. struct AddressMapping {
  31. // Address and size must be page-aligned
  32. VAddr address;
  33. u64 size;
  34. bool read_only;
  35. bool unk_flag;
  36. };
  37. enum class MemoryRegion : u16 {
  38. APPLICATION = 1,
  39. SYSTEM = 2,
  40. BASE = 3,
  41. };
  42. /**
  43. * Indicates the status of a Process instance.
  44. *
  45. * @note These match the values as used by kernel,
  46. * so new entries should only be added if RE
  47. * shows that a new value has been introduced.
  48. */
  49. enum class ProcessStatus {
  50. Created,
  51. CreatedWithDebuggerAttached,
  52. Running,
  53. WaitingForDebuggerToAttach,
  54. DebuggerAttached,
  55. Exiting,
  56. Exited,
  57. DebugBreak,
  58. };
  59. class Process final : public WaitObject {
  60. public:
  61. enum : u64 {
  62. /// Lowest allowed process ID for a kernel initial process.
  63. InitialKIPIDMin = 1,
  64. /// Highest allowed process ID for a kernel initial process.
  65. InitialKIPIDMax = 80,
  66. /// Lowest allowed process ID for a userland process.
  67. ProcessIDMin = 81,
  68. /// Highest allowed process ID for a userland process.
  69. ProcessIDMax = 0xFFFFFFFFFFFFFFFF,
  70. };
  71. static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
  72. static SharedPtr<Process> Create(Core::System& system, std::string&& name);
  73. std::string GetTypeName() const override {
  74. return "Process";
  75. }
  76. std::string GetName() const override {
  77. return name;
  78. }
  79. static const HandleType HANDLE_TYPE = HandleType::Process;
  80. HandleType GetHandleType() const override {
  81. return HANDLE_TYPE;
  82. }
  83. /// Gets a reference to the process' memory manager.
  84. Kernel::VMManager& VMManager() {
  85. return vm_manager;
  86. }
  87. /// Gets a const reference to the process' memory manager.
  88. const Kernel::VMManager& VMManager() const {
  89. return vm_manager;
  90. }
  91. /// Gets a reference to the process' handle table.
  92. HandleTable& GetHandleTable() {
  93. return handle_table;
  94. }
  95. /// Gets a const reference to the process' handle table.
  96. const HandleTable& GetHandleTable() const {
  97. return handle_table;
  98. }
  99. /// Gets a reference to the process' address arbiter.
  100. AddressArbiter& GetAddressArbiter() {
  101. return address_arbiter;
  102. }
  103. /// Gets a const reference to the process' address arbiter.
  104. const AddressArbiter& GetAddressArbiter() const {
  105. return address_arbiter;
  106. }
  107. /// Gets a reference to the process' mutex lock.
  108. Mutex& GetMutex() {
  109. return mutex;
  110. }
  111. /// Gets a const reference to the process' mutex lock
  112. const Mutex& GetMutex() const {
  113. return mutex;
  114. }
  115. /// Gets the current status of the process
  116. ProcessStatus GetStatus() const {
  117. return status;
  118. }
  119. /// Gets the unique ID that identifies this particular process.
  120. u64 GetProcessID() const {
  121. return process_id;
  122. }
  123. /// Gets the title ID corresponding to this process.
  124. u64 GetTitleID() const {
  125. return program_id;
  126. }
  127. /// Gets the resource limit descriptor for this process
  128. SharedPtr<ResourceLimit> GetResourceLimit() const;
  129. /// Gets the ideal CPU core ID for this process
  130. u8 GetIdealCore() const {
  131. return ideal_core;
  132. }
  133. /// Gets the bitmask of allowed cores that this process' threads can run on.
  134. u64 GetCoreMask() const {
  135. return capabilities.GetCoreMask();
  136. }
  137. /// Gets the bitmask of allowed thread priorities.
  138. u64 GetPriorityMask() const {
  139. return capabilities.GetPriorityMask();
  140. }
  141. u32 IsVirtualMemoryEnabled() const {
  142. return is_virtual_address_memory_enabled;
  143. }
  144. /// Whether this process is an AArch64 or AArch32 process.
  145. bool Is64BitProcess() const {
  146. return is_64bit_process;
  147. }
  148. /// Gets the total running time of the process instance in ticks.
  149. u64 GetCPUTimeTicks() const {
  150. return total_process_running_time_ticks;
  151. }
  152. /// Updates the total running time, adding the given ticks to it.
  153. void UpdateCPUTimeTicks(u64 ticks) {
  154. total_process_running_time_ticks += ticks;
  155. }
  156. /// Gets 8 bytes of random data for svcGetInfo RandomEntropy
  157. u64 GetRandomEntropy(std::size_t index) const {
  158. return random_entropy.at(index);
  159. }
  160. /// Clears the signaled state of the process if and only if it's signaled.
  161. ///
  162. /// @pre The process must not be already terminated. If this is called on a
  163. /// terminated process, then ERR_INVALID_STATE will be returned.
  164. ///
  165. /// @pre The process must be in a signaled state. If this is called on a
  166. /// process instance that is not signaled, ERR_INVALID_STATE will be
  167. /// returned.
  168. ResultCode ClearSignalState();
  169. /**
  170. * Loads process-specifics configuration info with metadata provided
  171. * by an executable.
  172. *
  173. * @param metadata The provided metadata to load process specific info from.
  174. *
  175. * @returns RESULT_SUCCESS if all relevant metadata was able to be
  176. * loaded and parsed. Otherwise, an error code is returned.
  177. */
  178. ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata);
  179. /**
  180. * Applies address space changes and launches the process main thread.
  181. */
  182. void Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size);
  183. /**
  184. * Prepares a process for termination by stopping all of its threads
  185. * and clearing any other resources.
  186. */
  187. void PrepareForTermination();
  188. void LoadModule(CodeSet module_, VAddr base_addr);
  189. ///////////////////////////////////////////////////////////////////////////////////////////////
  190. // Thread-local storage management
  191. // Marks the next available region as used and returns the address of the slot.
  192. VAddr MarkNextAvailableTLSSlotAsUsed(Thread& thread);
  193. // Frees a used TLS slot identified by the given address
  194. void FreeTLSSlot(VAddr tls_address);
  195. private:
  196. explicit Process(Core::System& system);
  197. ~Process() override;
  198. /// Checks if the specified thread should wait until this process is available.
  199. bool ShouldWait(Thread* thread) const override;
  200. /// Acquires/locks this process for the specified thread if it's available.
  201. void Acquire(Thread* thread) override;
  202. /// Changes the process status. If the status is different
  203. /// from the current process status, then this will trigger
  204. /// a process signal.
  205. void ChangeStatus(ProcessStatus new_status);
  206. /// Memory manager for this process.
  207. Kernel::VMManager vm_manager;
  208. /// Current status of the process
  209. ProcessStatus status;
  210. /// The ID of this process
  211. u64 process_id = 0;
  212. /// Title ID corresponding to the process
  213. u64 program_id = 0;
  214. /// Resource limit descriptor for this process
  215. SharedPtr<ResourceLimit> resource_limit;
  216. /// The ideal CPU core for this process, threads are scheduled on this core by default.
  217. u8 ideal_core = 0;
  218. u32 is_virtual_address_memory_enabled = 0;
  219. /// The Thread Local Storage area is allocated as processes create threads,
  220. /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
  221. /// holds the TLS for a specific thread. This vector contains which parts are in use for each
  222. /// page as a bitmask.
  223. /// This vector will grow as more pages are allocated for new threads.
  224. std::vector<std::bitset<8>> tls_slots;
  225. /// Contains the parsed process capability descriptors.
  226. ProcessCapabilities capabilities;
  227. /// Whether or not this process is AArch64, or AArch32.
  228. /// By default, we currently assume this is true, unless otherwise
  229. /// specified by metadata provided to the process during loading.
  230. bool is_64bit_process = true;
  231. /// Whether or not this process is signaled. This occurs
  232. /// upon the process changing to a different state.
  233. bool is_signaled = false;
  234. /// Total running time for the process in ticks.
  235. u64 total_process_running_time_ticks = 0;
  236. /// Per-process handle table for storing created object handles in.
  237. HandleTable handle_table;
  238. /// Per-process address arbiter.
  239. AddressArbiter address_arbiter;
  240. /// The per-process mutex lock instance used for handling various
  241. /// forms of services, such as lock arbitration, and condition
  242. /// variable related facilities.
  243. Mutex mutex;
  244. /// Random values for svcGetInfo RandomEntropy
  245. std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;
  246. /// System context
  247. Core::System& system;
  248. /// Name of this process
  249. std::string name;
  250. };
  251. } // namespace Kernel