k_process.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  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 <cstddef>
  7. #include <list>
  8. #include <string>
  9. #include <vector>
  10. #include "common/common_types.h"
  11. #include "core/hle/kernel/k_address_arbiter.h"
  12. #include "core/hle/kernel/k_auto_object.h"
  13. #include "core/hle/kernel/k_condition_variable.h"
  14. #include "core/hle/kernel/k_handle_table.h"
  15. #include "core/hle/kernel/k_synchronization_object.h"
  16. #include "core/hle/kernel/k_worker_task.h"
  17. #include "core/hle/kernel/process_capability.h"
  18. #include "core/hle/kernel/slab_helpers.h"
  19. #include "core/hle/result.h"
  20. namespace Core {
  21. class System;
  22. }
  23. namespace FileSys {
  24. class ProgramMetadata;
  25. }
  26. namespace Kernel {
  27. class KernelCore;
  28. class KPageTable;
  29. class KResourceLimit;
  30. class KThread;
  31. class KSharedMemoryInfo;
  32. class TLSPage;
  33. struct CodeSet;
  34. enum class MemoryRegion : u16 {
  35. APPLICATION = 1,
  36. SYSTEM = 2,
  37. BASE = 3,
  38. };
  39. /**
  40. * Indicates the status of a Process instance.
  41. *
  42. * @note These match the values as used by kernel,
  43. * so new entries should only be added if RE
  44. * shows that a new value has been introduced.
  45. */
  46. enum class ProcessStatus {
  47. Created,
  48. CreatedWithDebuggerAttached,
  49. Running,
  50. WaitingForDebuggerToAttach,
  51. DebuggerAttached,
  52. Exiting,
  53. Exited,
  54. DebugBreak,
  55. };
  56. class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> {
  57. KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject);
  58. public:
  59. explicit KProcess(KernelCore& kernel_);
  60. ~KProcess() override;
  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. // Used to determine how process IDs are assigned.
  72. enum class ProcessType {
  73. KernelInternal,
  74. Userland,
  75. };
  76. static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
  77. static ResultCode Initialize(KProcess* process, Core::System& system, std::string process_name,
  78. ProcessType type, KResourceLimit* res_limit);
  79. /// Gets a reference to the process' page table.
  80. KPageTable& PageTable() {
  81. return *page_table;
  82. }
  83. /// Gets const a reference to the process' page table.
  84. const KPageTable& PageTable() const {
  85. return *page_table;
  86. }
  87. /// Gets a reference to the process' handle table.
  88. KHandleTable& GetHandleTable() {
  89. return handle_table;
  90. }
  91. /// Gets a const reference to the process' handle table.
  92. const KHandleTable& GetHandleTable() const {
  93. return handle_table;
  94. }
  95. ResultCode SignalToAddress(VAddr address) {
  96. return condition_var.SignalToAddress(address);
  97. }
  98. ResultCode WaitForAddress(Handle handle, VAddr address, u32 tag) {
  99. return condition_var.WaitForAddress(handle, address, tag);
  100. }
  101. void SignalConditionVariable(u64 cv_key, int32_t count) {
  102. return condition_var.Signal(cv_key, count);
  103. }
  104. ResultCode WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) {
  105. return condition_var.Wait(address, cv_key, tag, ns);
  106. }
  107. ResultCode SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value,
  108. s32 count) {
  109. return address_arbiter.SignalToAddress(address, signal_type, value, count);
  110. }
  111. ResultCode WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value,
  112. s64 timeout) {
  113. return address_arbiter.WaitForAddress(address, arb_type, value, timeout);
  114. }
  115. /// Gets the address to the process' dedicated TLS region.
  116. VAddr GetTLSRegionAddress() const {
  117. return tls_region_address;
  118. }
  119. /// Gets the current status of the process
  120. ProcessStatus GetStatus() const {
  121. return status;
  122. }
  123. /// Gets the unique ID that identifies this particular process.
  124. u64 GetProcessID() const {
  125. return process_id;
  126. }
  127. /// Gets the program ID corresponding to this process.
  128. u64 GetProgramID() const {
  129. return program_id;
  130. }
  131. /// Gets the resource limit descriptor for this process
  132. KResourceLimit* GetResourceLimit() const;
  133. /// Gets the ideal CPU core ID for this process
  134. u8 GetIdealCoreId() const {
  135. return ideal_core;
  136. }
  137. /// Checks if the specified thread priority is valid.
  138. bool CheckThreadPriority(s32 prio) const {
  139. return ((1ULL << prio) & GetPriorityMask()) != 0;
  140. }
  141. /// Gets the bitmask of allowed cores that this process' threads can run on.
  142. u64 GetCoreMask() const {
  143. return capabilities.GetCoreMask();
  144. }
  145. /// Gets the bitmask of allowed thread priorities.
  146. u64 GetPriorityMask() const {
  147. return capabilities.GetPriorityMask();
  148. }
  149. /// Gets the amount of secure memory to allocate for memory management.
  150. u32 GetSystemResourceSize() const {
  151. return system_resource_size;
  152. }
  153. /// Gets the amount of secure memory currently in use for memory management.
  154. u32 GetSystemResourceUsage() const {
  155. // On hardware, this returns the amount of system resource memory that has
  156. // been used by the kernel. This is problematic for Yuzu to emulate, because
  157. // system resource memory is used for page tables -- and yuzu doesn't really
  158. // have a way to calculate how much memory is required for page tables for
  159. // the current process at any given time.
  160. // TODO: Is this even worth implementing? Games may retrieve this value via
  161. // an SDK function that gets used + available system resource size for debug
  162. // or diagnostic purposes. However, it seems unlikely that a game would make
  163. // decisions based on how much system memory is dedicated to its page tables.
  164. // Is returning a value other than zero wise?
  165. return 0;
  166. }
  167. /// Whether this process is an AArch64 or AArch32 process.
  168. bool Is64BitProcess() const {
  169. return is_64bit_process;
  170. }
  171. [[nodiscard]] bool IsSuspended() const {
  172. return is_suspended;
  173. }
  174. void SetSuspended(bool suspended) {
  175. is_suspended = suspended;
  176. }
  177. /// Gets the total running time of the process instance in ticks.
  178. u64 GetCPUTimeTicks() const {
  179. return total_process_running_time_ticks;
  180. }
  181. /// Updates the total running time, adding the given ticks to it.
  182. void UpdateCPUTimeTicks(u64 ticks) {
  183. total_process_running_time_ticks += ticks;
  184. }
  185. /// Gets the process schedule count, used for thread yelding
  186. s64 GetScheduledCount() const {
  187. return schedule_count;
  188. }
  189. /// Increments the process schedule count, used for thread yielding.
  190. void IncrementScheduledCount() {
  191. ++schedule_count;
  192. }
  193. void IncrementRunningThreadCount();
  194. void DecrementRunningThreadCount();
  195. void SetRunningThread(s32 core, KThread* thread, u64 idle_count) {
  196. running_threads[core] = thread;
  197. running_thread_idle_counts[core] = idle_count;
  198. }
  199. void ClearRunningThread(KThread* thread) {
  200. for (size_t i = 0; i < running_threads.size(); ++i) {
  201. if (running_threads[i] == thread) {
  202. running_threads[i] = nullptr;
  203. }
  204. }
  205. }
  206. [[nodiscard]] KThread* GetRunningThread(s32 core) const {
  207. return running_threads[core];
  208. }
  209. bool ReleaseUserException(KThread* thread);
  210. [[nodiscard]] KThread* GetPinnedThread(s32 core_id) const {
  211. ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
  212. return pinned_threads[core_id];
  213. }
  214. /// Gets 8 bytes of random data for svcGetInfo RandomEntropy
  215. u64 GetRandomEntropy(std::size_t index) const {
  216. return random_entropy.at(index);
  217. }
  218. /// Retrieves the total physical memory available to this process in bytes.
  219. u64 GetTotalPhysicalMemoryAvailable() const;
  220. /// Retrieves the total physical memory available to this process in bytes,
  221. /// without the size of the personal system resource heap added to it.
  222. u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource() const;
  223. /// Retrieves the total physical memory used by this process in bytes.
  224. u64 GetTotalPhysicalMemoryUsed() const;
  225. /// Retrieves the total physical memory used by this process in bytes,
  226. /// without the size of the personal system resource heap added to it.
  227. u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const;
  228. /// Gets the list of all threads created with this process as their owner.
  229. const std::list<const KThread*>& GetThreadList() const {
  230. return thread_list;
  231. }
  232. /// Registers a thread as being created under this process,
  233. /// adding it to this process' thread list.
  234. void RegisterThread(const KThread* thread);
  235. /// Unregisters a thread from this process, removing it
  236. /// from this process' thread list.
  237. void UnregisterThread(const KThread* thread);
  238. /// Clears the signaled state of the process if and only if it's signaled.
  239. ///
  240. /// @pre The process must not be already terminated. If this is called on a
  241. /// terminated process, then ERR_INVALID_STATE will be returned.
  242. ///
  243. /// @pre The process must be in a signaled state. If this is called on a
  244. /// process instance that is not signaled, ERR_INVALID_STATE will be
  245. /// returned.
  246. ResultCode Reset();
  247. /**
  248. * Loads process-specifics configuration info with metadata provided
  249. * by an executable.
  250. *
  251. * @param metadata The provided metadata to load process specific info from.
  252. *
  253. * @returns ResultSuccess if all relevant metadata was able to be
  254. * loaded and parsed. Otherwise, an error code is returned.
  255. */
  256. ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size);
  257. /**
  258. * Starts the main application thread for this process.
  259. *
  260. * @param main_thread_priority The priority for the main thread.
  261. * @param stack_size The stack size for the main thread in bytes.
  262. */
  263. void Run(s32 main_thread_priority, u64 stack_size);
  264. /**
  265. * Prepares a process for termination by stopping all of its threads
  266. * and clearing any other resources.
  267. */
  268. void PrepareForTermination();
  269. void LoadModule(CodeSet code_set, VAddr base_addr);
  270. bool IsInitialized() const override {
  271. return is_initialized;
  272. }
  273. static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
  274. void Finalize() override;
  275. u64 GetId() const override {
  276. return GetProcessID();
  277. }
  278. bool IsSignaled() const override;
  279. void DoWorkerTaskImpl();
  280. void PinCurrentThread(s32 core_id);
  281. void UnpinCurrentThread(s32 core_id);
  282. void UnpinThread(KThread* thread);
  283. KLightLock& GetStateLock() {
  284. return state_lock;
  285. }
  286. ResultCode AddSharedMemory(KSharedMemory* shmem, VAddr address, size_t size);
  287. void RemoveSharedMemory(KSharedMemory* shmem, VAddr address, size_t size);
  288. ///////////////////////////////////////////////////////////////////////////////////////////////
  289. // Thread-local storage management
  290. // Marks the next available region as used and returns the address of the slot.
  291. [[nodiscard]] VAddr CreateTLSRegion();
  292. // Frees a used TLS slot identified by the given address
  293. void FreeTLSRegion(VAddr tls_address);
  294. private:
  295. void PinThread(s32 core_id, KThread* thread) {
  296. ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
  297. ASSERT(thread != nullptr);
  298. ASSERT(pinned_threads[core_id] == nullptr);
  299. pinned_threads[core_id] = thread;
  300. }
  301. void UnpinThread(s32 core_id, KThread* thread) {
  302. ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
  303. ASSERT(thread != nullptr);
  304. ASSERT(pinned_threads[core_id] == thread);
  305. pinned_threads[core_id] = nullptr;
  306. }
  307. /// Changes the process status. If the status is different
  308. /// from the current process status, then this will trigger
  309. /// a process signal.
  310. void ChangeStatus(ProcessStatus new_status);
  311. /// Allocates the main thread stack for the process, given the stack size in bytes.
  312. ResultCode AllocateMainThreadStack(std::size_t stack_size);
  313. /// Memory manager for this process
  314. std::unique_ptr<KPageTable> page_table;
  315. /// Current status of the process
  316. ProcessStatus status{};
  317. /// The ID of this process
  318. u64 process_id = 0;
  319. /// Title ID corresponding to the process
  320. u64 program_id = 0;
  321. /// Specifies additional memory to be reserved for the process's memory management by the
  322. /// system. When this is non-zero, secure memory is allocated and used for page table allocation
  323. /// instead of using the normal global page tables/memory block management.
  324. u32 system_resource_size = 0;
  325. /// Resource limit descriptor for this process
  326. KResourceLimit* resource_limit{};
  327. /// The ideal CPU core for this process, threads are scheduled on this core by default.
  328. u8 ideal_core = 0;
  329. /// The Thread Local Storage area is allocated as processes create threads,
  330. /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
  331. /// holds the TLS for a specific thread. This vector contains which parts are in use for each
  332. /// page as a bitmask.
  333. /// This vector will grow as more pages are allocated for new threads.
  334. std::vector<TLSPage> tls_pages;
  335. /// Contains the parsed process capability descriptors.
  336. ProcessCapabilities capabilities;
  337. /// Whether or not this process is AArch64, or AArch32.
  338. /// By default, we currently assume this is true, unless otherwise
  339. /// specified by metadata provided to the process during loading.
  340. bool is_64bit_process = true;
  341. /// Total running time for the process in ticks.
  342. u64 total_process_running_time_ticks = 0;
  343. /// Per-process handle table for storing created object handles in.
  344. KHandleTable handle_table;
  345. /// Per-process address arbiter.
  346. KAddressArbiter address_arbiter;
  347. /// The per-process mutex lock instance used for handling various
  348. /// forms of services, such as lock arbitration, and condition
  349. /// variable related facilities.
  350. KConditionVariable condition_var;
  351. /// Address indicating the location of the process' dedicated TLS region.
  352. VAddr tls_region_address = 0;
  353. /// Random values for svcGetInfo RandomEntropy
  354. std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{};
  355. /// List of threads that are running with this process as their owner.
  356. std::list<const KThread*> thread_list;
  357. /// List of shared memory that are running with this process as their owner.
  358. std::list<KSharedMemoryInfo*> shared_memory_list;
  359. /// Address of the top of the main thread's stack
  360. VAddr main_thread_stack_top{};
  361. /// Size of the main thread's stack
  362. std::size_t main_thread_stack_size{};
  363. /// Memory usage capacity for the process
  364. std::size_t memory_usage_capacity{};
  365. /// Process total image size
  366. std::size_t image_size{};
  367. /// Schedule count of this process
  368. s64 schedule_count{};
  369. bool is_signaled{};
  370. bool is_suspended{};
  371. bool is_initialized{};
  372. std::atomic<u16> num_running_threads{};
  373. std::array<KThread*, Core::Hardware::NUM_CPU_CORES> running_threads{};
  374. std::array<u64, Core::Hardware::NUM_CPU_CORES> running_thread_idle_counts{};
  375. std::array<KThread*, Core::Hardware::NUM_CPU_CORES> pinned_threads{};
  376. KThread* exception_thread{};
  377. KLightLock state_lock;
  378. };
  379. } // namespace Kernel