process.h 11 KB

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