| 
									
										
										
										
											2014-05-09 22:11:18 -04:00
										 |  |  | // Copyright 2014 Citra Emulator Project / PPSSPP Project
 | 
					
						
							| 
									
										
										
										
											2014-12-16 21:38:14 -08:00
										 |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							| 
									
										
										
										
											2014-11-19 08:49:13 +00:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2014-05-09 22:11:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-31 08:06:09 -04:00
										 |  |  | #include <functional>
 | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2018-07-31 08:06:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 22:11:18 -04:00
										 |  |  | #include "common/common_types.h"
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | #include "common/spin_lock.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-22 00:08:09 -05:00
										 |  |  | #include "core/arm/arm_interface.h"
 | 
					
						
							| 
									
										
										
										
											2018-08-01 22:40:00 -04:00
										 |  |  | #include "core/hle/kernel/object.h"
 | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  | #include "core/hle/kernel/synchronization_object.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-23 01:20:01 -02:00
										 |  |  | #include "core/hle/result.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-09 22:11:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | namespace Common { | 
					
						
							|  |  |  | class Fiber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Core { | 
					
						
							|  |  |  | class System; | 
					
						
							| 
									
										
										
										
											2020-03-03 13:37:11 -04:00
										 |  |  | } // namespace Core
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 15:57:45 -04:00
										 |  |  | namespace Kernel { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | class GlobalScheduler; | 
					
						
							| 
									
										
										
										
											2018-09-13 15:57:45 -04:00
										 |  |  | class KernelCore; | 
					
						
							|  |  |  | class Process; | 
					
						
							|  |  |  | class Scheduler; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 00:26:09 +01:00
										 |  |  | enum ThreadPriority : u32 { | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     THREADPRIO_HIGHEST = 0,            ///< Highest thread priority
 | 
					
						
							|  |  |  |     THREADPRIO_MAX_CORE_MIGRATION = 2, ///< Highest priority for a core migration
 | 
					
						
							|  |  |  |     THREADPRIO_USERLAND_MAX = 24,      ///< Highest thread priority for userland apps
 | 
					
						
							|  |  |  |     THREADPRIO_DEFAULT = 44,           ///< Default thread priority for userland apps
 | 
					
						
							|  |  |  |     THREADPRIO_LOWEST = 63,            ///< Lowest thread priority
 | 
					
						
							|  |  |  |     THREADPRIO_COUNT = 64,             ///< Total number of possible thread priorities.
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum ThreadType : u32 { | 
					
						
							|  |  |  |     THREADTYPE_USER = 0x1, | 
					
						
							|  |  |  |     THREADTYPE_KERNEL = 0x2, | 
					
						
							|  |  |  |     THREADTYPE_HLE = 0x4, | 
					
						
							|  |  |  |     THREADTYPE_IDLE = 0x8, | 
					
						
							|  |  |  |     THREADTYPE_SUSPEND = 0x10, | 
					
						
							| 
									
										
										
										
											2014-05-17 00:56:00 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 23:55:21 -04:00
										 |  |  | enum ThreadProcessorId : s32 { | 
					
						
							| 
									
										
										
										
											2019-04-15 20:17:15 -04:00
										 |  |  |     /// Indicates that no particular processor core is preferred.
 | 
					
						
							|  |  |  |     THREADPROCESSORID_DONT_CARE = -1, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Run thread on the ideal core specified by the process.
 | 
					
						
							|  |  |  |     THREADPROCESSORID_IDEAL = -2, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Indicates that the preferred processor ID shouldn't be updated in
 | 
					
						
							|  |  |  |     /// a core mask setting operation.
 | 
					
						
							|  |  |  |     THREADPROCESSORID_DONT_UPDATE = -3, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     THREADPROCESSORID_0 = 0,   ///< Run thread on core 0
 | 
					
						
							|  |  |  |     THREADPROCESSORID_1 = 1,   ///< Run thread on core 1
 | 
					
						
							|  |  |  |     THREADPROCESSORID_2 = 2,   ///< Run thread on core 2
 | 
					
						
							|  |  |  |     THREADPROCESSORID_3 = 3,   ///< Run thread on core 3
 | 
					
						
							|  |  |  |     THREADPROCESSORID_MAX = 4, ///< Processor ID must be less than this
 | 
					
						
							| 
									
										
										
										
											2018-01-10 00:58:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Allowed CPU mask
 | 
					
						
							|  |  |  |     THREADPROCESSORID_DEFAULT_MASK = (1 << THREADPROCESSORID_0) | (1 << THREADPROCESSORID_1) | | 
					
						
							|  |  |  |                                      (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3) | 
					
						
							| 
									
										
										
										
											2014-05-17 00:56:00 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-19 21:39:05 -04:00
										 |  |  | enum class ThreadStatus { | 
					
						
							|  |  |  |     Running,      ///< Currently running
 | 
					
						
							|  |  |  |     Ready,        ///< Ready to run
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:25:27 -05:00
										 |  |  |     Paused,       ///< Paused by SetThreadActivity or debug
 | 
					
						
							| 
									
										
										
										
											2018-07-19 21:39:05 -04:00
										 |  |  |     WaitHLEEvent, ///< Waiting for hle event to finish
 | 
					
						
							|  |  |  |     WaitSleep,    ///< Waiting due to a SleepThread SVC
 | 
					
						
							|  |  |  |     WaitIPC,      ///< Waiting for the reply from an IPC request
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |     WaitSynch,    ///< Waiting due to WaitSynchronization
 | 
					
						
							| 
									
										
										
										
											2019-03-13 19:55:04 -04:00
										 |  |  |     WaitMutex,    ///< Waiting due to an ArbitrateLock svc
 | 
					
						
							|  |  |  |     WaitCondVar,  ///< Waiting due to an WaitProcessWideKey svc
 | 
					
						
							| 
									
										
										
										
											2018-07-19 21:39:05 -04:00
										 |  |  |     WaitArb,      ///< Waiting due to a SignalToAddress/WaitForAddress svc
 | 
					
						
							|  |  |  |     Dormant,      ///< Created but not yet made ready
 | 
					
						
							|  |  |  |     Dead          ///< Run to completion, or forcefully terminated
 | 
					
						
							| 
									
										
										
										
											2014-05-22 18:50:36 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-28 11:53:32 -05:00
										 |  |  | enum class ThreadWakeupReason { | 
					
						
							|  |  |  |     Signal, // The thread was woken up by WakeupAllWaitingThreads due to an object signal.
 | 
					
						
							|  |  |  |     Timeout // The thread was woken up due to a wait timeout.
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:25:27 -05:00
										 |  |  | enum class ThreadActivity : u32 { | 
					
						
							|  |  |  |     Normal = 0, | 
					
						
							|  |  |  |     Paused = 1, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 09:11:18 -04:00
										 |  |  | enum class ThreadSchedStatus : u32 { | 
					
						
							|  |  |  |     None = 0, | 
					
						
							|  |  |  |     Paused = 1, | 
					
						
							|  |  |  |     Runnable = 2, | 
					
						
							|  |  |  |     Exited = 3, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 10:13:25 -04:00
										 |  |  | enum class ThreadSchedFlags : u32 { | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     ProcessPauseFlag = 1 << 4, | 
					
						
							|  |  |  |     ThreadPauseFlag = 1 << 5, | 
					
						
							|  |  |  |     ProcessDebugPauseFlag = 1 << 6, | 
					
						
							|  |  |  |     KernelInitPauseFlag = 1 << 8, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 10:13:25 -04:00
										 |  |  | enum class ThreadSchedMasks : u32 { | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     LowMask = 0x000f, | 
					
						
							|  |  |  |     HighMask = 0xfff0, | 
					
						
							|  |  |  |     ForcePauseMask = 0x0070, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  | class Thread final : public SynchronizationObject { | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     explicit Thread(KernelCore& kernel); | 
					
						
							|  |  |  |     ~Thread() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     using ThreadContext32 = Core::ARM_Interface::ThreadContext32; | 
					
						
							|  |  |  |     using ThreadContext64 = Core::ARM_Interface::ThreadContext64; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |     using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     using WakeupCallback = | 
					
						
							|  |  |  |         std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |                            std::shared_ptr<SynchronizationObject> object, std::size_t index)>; | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     using HLECallback = std::function<bool(std::shared_ptr<Thread> thread)>; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Creates and returns a new thread. The new thread is immediately scheduled | 
					
						
							|  |  |  |      * @param system The instance of the whole system | 
					
						
							|  |  |  |      * @param name The friendly name desired for the thread | 
					
						
							|  |  |  |      * @param entry_point The address at which the thread should start execution | 
					
						
							|  |  |  |      * @param priority The thread's priority | 
					
						
							|  |  |  |      * @param arg User data to pass to the thread | 
					
						
							|  |  |  |      * @param processor_id The ID(s) of the processors on which the thread is desired to be run | 
					
						
							|  |  |  |      * @param stack_top The address of the thread's stack top | 
					
						
							|  |  |  |      * @param owner_process The parent process for the thread, if null, it's a kernel thread | 
					
						
							|  |  |  |      * @return A shared pointer to the newly created thread | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags, | 
					
						
							|  |  |  |                                                      std::string name, VAddr entry_point, | 
					
						
							|  |  |  |                                                      u32 priority, u64 arg, s32 processor_id, | 
					
						
							|  |  |  |                                                      VAddr stack_top, Process* owner_process); | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Creates and returns a new thread. The new thread is immediately scheduled | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |      * @param system The instance of the whole system | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |      * @param name The friendly name desired for the thread | 
					
						
							|  |  |  |      * @param entry_point The address at which the thread should start execution | 
					
						
							|  |  |  |      * @param priority The thread's priority | 
					
						
							|  |  |  |      * @param arg User data to pass to the thread | 
					
						
							|  |  |  |      * @param processor_id The ID(s) of the processors on which the thread is desired to be run | 
					
						
							|  |  |  |      * @param stack_top The address of the thread's stack top | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |      * @param owner_process The parent process for the thread, if null, it's a kernel thread | 
					
						
							|  |  |  |      * @param thread_start_func The function where the host context will start. | 
					
						
							|  |  |  |      * @param thread_start_parameter The parameter which will passed to host context on init | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |      * @return A shared pointer to the newly created thread | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags, | 
					
						
							|  |  |  |                                                      std::string name, VAddr entry_point, | 
					
						
							|  |  |  |                                                      u32 priority, u64 arg, s32 processor_id, | 
					
						
							|  |  |  |                                                      VAddr stack_top, Process* owner_process, | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |                                                      std::function<void(void*)>&& thread_start_func, | 
					
						
							|  |  |  |                                                      void* thread_start_parameter); | 
					
						
							| 
									
										
										
										
											2014-12-22 11:07:22 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |     std::string GetName() const override { | 
					
						
							|  |  |  |         return name; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-15 15:54:25 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void SetName(std::string new_name) { | 
					
						
							|  |  |  |         name = std::move(new_name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |     std::string GetTypeName() const override { | 
					
						
							|  |  |  |         return "Thread"; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 16:30:52 -04:00
										 |  |  |     static constexpr HandleType HANDLE_TYPE = HandleType::Thread; | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |     HandleType GetHandleType() const override { | 
					
						
							|  |  |  |         return HANDLE_TYPE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-01 18:19:42 -04:00
										 |  |  |     bool ShouldWait(const Thread* thread) const override; | 
					
						
							| 
									
										
										
										
											2017-01-01 16:53:22 -05:00
										 |  |  |     void Acquire(Thread* thread) override; | 
					
						
							| 
									
										
										
										
											2020-02-11 17:36:39 -04:00
										 |  |  |     bool IsSignaled() const override; | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Gets the thread's current priority | 
					
						
							|  |  |  |      * @return The current thread's priority | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-09-27 00:26:09 +01:00
										 |  |  |     u32 GetPriority() const { | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |         return current_priority; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Gets the thread's nominal priority. | 
					
						
							|  |  |  |      * @return The current thread's nominal priority. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     u32 GetNominalPriority() const { | 
					
						
							|  |  |  |         return nominal_priority; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Sets the thread's current priority | 
					
						
							|  |  |  |      * @param priority The new priority | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-09-27 00:26:09 +01:00
										 |  |  |     void SetPriority(u32 priority); | 
					
						
							| 
									
										
										
										
											2014-12-22 11:07:22 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-20 20:15:16 -05:00
										 |  |  |     /// Adds a thread to the list of threads that are waiting for a lock held by this thread.
 | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     void AddMutexWaiter(std::shared_ptr<Thread> thread); | 
					
						
							| 
									
										
										
										
											2018-04-20 20:15:16 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Removes a thread from the list of threads that are waiting for a lock held by this thread.
 | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     void RemoveMutexWaiter(std::shared_ptr<Thread> thread); | 
					
						
							| 
									
										
										
										
											2018-04-20 20:15:16 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Recalculates the current priority taking into account priority inheritance.
 | 
					
						
							|  |  |  |     void UpdatePriority(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-05 23:03:01 -04:00
										 |  |  |     /// Changes the core that the thread is running or scheduled to run on.
 | 
					
						
							| 
									
										
										
										
											2020-02-25 13:22:11 -04:00
										 |  |  |     ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask); | 
					
						
							| 
									
										
										
										
											2018-05-05 23:03:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Gets the thread's thread ID | 
					
						
							|  |  |  |      * @return The thread's ID | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-12-18 22:37:01 -05:00
										 |  |  |     u64 GetThreadID() const { | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |         return thread_id; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-25 20:34:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:08:12 -04:00
										 |  |  |     /// Resumes a thread from waiting
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     void /* deprecated */ ResumeFromWait(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void OnWakeUp(); | 
					
						
							| 
									
										
										
										
											2014-12-22 11:07:22 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  |     ResultCode Start(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:08:12 -04:00
										 |  |  |     /// Cancels a waiting operation that this thread may or may not be within.
 | 
					
						
							|  |  |  |     ///
 | 
					
						
							|  |  |  |     /// When the thread is within a waiting state, this will set the thread's
 | 
					
						
							|  |  |  |     /// waiting result to signal a canceled wait. The function will then resume
 | 
					
						
							|  |  |  |     /// this thread.
 | 
					
						
							|  |  |  |     ///
 | 
					
						
							|  |  |  |     void CancelWait(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-30 23:07:54 -02:00
										 |  |  |     /**
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:40:49 -05:00
										 |  |  |      * Schedules an event to wake up the specified thread after the specified delay | 
					
						
							|  |  |  |      * @param nanoseconds The time this thread will be allowed to sleep for | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     void /* deprecated */ WakeAfterDelay(s64 nanoseconds); | 
					
						
							| 
									
										
										
										
											2015-01-30 23:07:54 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-08 11:35:03 -05:00
										 |  |  |     /// Cancel any outstanding wakeup events for this thread
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     void /* deprecated */ CancelWakeupTimer(); | 
					
						
							| 
									
										
										
										
											2018-01-08 11:35:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 02:03:44 -05:00
										 |  |  |     /**
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |      * Sets the result after the thread awakens (from svcWaitSynchronization) | 
					
						
							| 
									
										
										
										
											2015-01-20 20:53:52 -05:00
										 |  |  |      * @param result Value to set to the returned result | 
					
						
							| 
									
										
										
										
											2015-01-17 02:03:44 -05:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-02-25 16:38:33 -04:00
										 |  |  |     void /*deprecated*/ SetWaitSynchronizationResult(ResultCode result); | 
					
						
							| 
									
										
										
										
											2015-01-20 20:53:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |      * Sets the output parameter value after the thread awakens (from svcWaitSynchronization) | 
					
						
							| 
									
										
										
										
											2015-01-20 20:53:52 -05:00
										 |  |  |      * @param output Value to set to the output parameter | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-02-25 16:38:33 -04:00
										 |  |  |     void /*deprecated*/ SetWaitSynchronizationOutput(s32 output); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SynchronizationObject* GetSignalingObject() const { | 
					
						
							|  |  |  |         return signaling_object; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ResultCode GetSignalingResult() const { | 
					
						
							|  |  |  |         return signaling_result; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-17 02:03:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-03 22:38:14 -05:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Retrieves the index that this particular object occupies in the list of objects | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |      * that the thread passed to WaitSynchronization, starting the search from the last element. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * It is used to set the output index of WaitSynchronization when the thread is awakened. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-01-04 10:53:01 -05:00
										 |  |  |      * When a thread wakes up due to an object signal, the kernel will use the index of the last | 
					
						
							|  |  |  |      * matching object in the wait objects list in case of having multiple instances of the same | 
					
						
							|  |  |  |      * object in the list. | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2016-12-03 22:38:14 -05:00
										 |  |  |      * @param object Object to query the index of. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |     s32 GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const; | 
					
						
							| 
									
										
										
										
											2016-12-03 22:38:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Stops a thread, invalidating it from further use | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     void Stop(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-10 18:35:37 -05:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Returns the Thread Local Storage address of the current thread | 
					
						
							|  |  |  |      * @returns VAddr of the thread's TLS | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |     VAddr GetTLSAddress() const { | 
					
						
							|  |  |  |         return tls_address; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-10 18:35:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 19:57:45 -05:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Returns the value of the TPIDR_EL0 Read/Write system register for this thread. | 
					
						
							|  |  |  |      * @returns The value of the TPIDR_EL0 register. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     u64 GetTPIDR_EL0() const { | 
					
						
							|  |  |  |         return tpidr_el0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /// Sets the value of the TPIDR_EL0 Read/Write system register for this thread.
 | 
					
						
							|  |  |  |     void SetTPIDR_EL0(u64 value) { | 
					
						
							|  |  |  |         tpidr_el0 = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-29 14:47:52 -05:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Returns the address of the current thread's command buffer, located in the TLS. | 
					
						
							|  |  |  |      * @returns VAddr of the thread's command buffer. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     VAddr GetCommandBufferAddress() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |     /// Returns whether this thread is waiting on objects from a WaitSynchronization call.
 | 
					
						
							|  |  |  |     bool IsSleepingOnWait() const { | 
					
						
							|  |  |  |         return status == ThreadStatus::WaitSynch; | 
					
						
							| 
									
										
										
										
											2016-12-04 09:58:36 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     ThreadContext32& GetContext32() { | 
					
						
							|  |  |  |         return context_32; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     const ThreadContext32& GetContext32() const { | 
					
						
							|  |  |  |         return context_32; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ThreadContext64& GetContext64() { | 
					
						
							|  |  |  |         return context_64; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const ThreadContext64& GetContext64() const { | 
					
						
							|  |  |  |         return context_64; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     bool IsHLEThread() const { | 
					
						
							|  |  |  |         return (type & THREADTYPE_HLE) != 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::shared_ptr<Common::Fiber> GetHostContext() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     ThreadStatus GetStatus() const { | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetStatus(ThreadStatus new_status); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u64 GetLastRunningTicks() const { | 
					
						
							|  |  |  |         return last_running_ticks; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 18:42:50 -04:00
										 |  |  |     u64 GetTotalCPUTimeTicks() const { | 
					
						
							|  |  |  |         return total_cpu_time_ticks; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void UpdateCPUTimeTicks(u64 ticks) { | 
					
						
							|  |  |  |         total_cpu_time_ticks += ticks; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     s32 GetProcessorID() const { | 
					
						
							|  |  |  |         return processor_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     void SetProcessorID(s32 new_core) { | 
					
						
							|  |  |  |         processor_id = new_core; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 00:42:10 -04:00
										 |  |  |     Process* GetOwnerProcess() { | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |         return owner_process; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 00:42:10 -04:00
										 |  |  |     const Process* GetOwnerProcess() const { | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |         return owner_process; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |     const ThreadSynchronizationObjects& GetSynchronizationObjects() const { | 
					
						
							| 
									
										
										
										
											2020-03-03 13:37:11 -04:00
										 |  |  |         return *wait_objects; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 13:37:11 -04:00
										 |  |  |     void SetSynchronizationObjects(ThreadSynchronizationObjects* objects) { | 
					
						
							|  |  |  |         wait_objects = objects; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |     void ClearSynchronizationObjects() { | 
					
						
							| 
									
										
										
										
											2020-03-03 13:37:11 -04:00
										 |  |  |         for (const auto& waiting_object : *wait_objects) { | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |             waiting_object->RemoveWaitingThread(SharedFrom(this)); | 
					
						
							| 
									
										
										
										
											2019-10-10 08:04:14 -04:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-03-03 13:37:11 -04:00
										 |  |  |         wait_objects->clear(); | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Determines whether all the objects this thread is waiting on are ready.
 | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |     bool AllSynchronizationObjectsReady() const; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const MutexWaitingThreads& GetMutexWaitingThreads() const { | 
					
						
							|  |  |  |         return wait_mutex_threads; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Thread* GetLockOwner() const { | 
					
						
							|  |  |  |         return lock_owner.get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     void SetLockOwner(std::shared_ptr<Thread> owner) { | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |         lock_owner = std::move(owner); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VAddr GetCondVarWaitAddress() const { | 
					
						
							|  |  |  |         return condvar_wait_address; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetCondVarWaitAddress(VAddr address) { | 
					
						
							|  |  |  |         condvar_wait_address = address; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VAddr GetMutexWaitAddress() const { | 
					
						
							|  |  |  |         return mutex_wait_address; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     void SetMutexWaitAddress(VAddr address) { | 
					
						
							|  |  |  |         mutex_wait_address = address; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     Handle GetWaitHandle() const { | 
					
						
							|  |  |  |         return wait_handle; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     void SetWaitHandle(Handle handle) { | 
					
						
							|  |  |  |         wait_handle = handle; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-23 23:55:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     VAddr GetArbiterWaitAddress() const { | 
					
						
							|  |  |  |         return arb_wait_address; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     void SetArbiterWaitAddress(VAddr address) { | 
					
						
							|  |  |  |         arb_wait_address = address; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     bool HasWakeupCallback() const { | 
					
						
							| 
									
										
										
										
											2020-03-03 13:02:50 -04:00
										 |  |  |         return wakeup_callback != nullptr; | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool HasHLECallback() const { | 
					
						
							|  |  |  |         return hle_callback != nullptr; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetWakeupCallback(WakeupCallback callback) { | 
					
						
							| 
									
										
										
										
											2020-03-03 13:02:50 -04:00
										 |  |  |         wakeup_callback = std::move(callback); | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 13:02:50 -04:00
										 |  |  |     void SetHLECallback(HLECallback callback) { | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |         hle_callback = std::move(callback); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetHLETimeEvent(Handle time_event) { | 
					
						
							|  |  |  |         hle_time_event = time_event; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Handle GetHLETimeEvent() const { | 
					
						
							|  |  |  |         return hle_time_event; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void InvalidateWakeupCallback() { | 
					
						
							|  |  |  |         SetWakeupCallback(nullptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     void InvalidateHLECallback() { | 
					
						
							|  |  |  |         SetHLECallback(nullptr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Invokes the thread's wakeup callback. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @pre A valid wakeup callback has been set. Violating this precondition | 
					
						
							|  |  |  |      *      will cause an assertion to trigger. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 
					
						
							| 
									
										
										
										
											2020-02-11 10:46:25 -04:00
										 |  |  |                               std::shared_ptr<SynchronizationObject> object, std::size_t index); | 
					
						
							| 
									
										
										
										
											2020-03-03 13:02:50 -04:00
										 |  |  |     bool InvokeHLECallback(std::shared_ptr<Thread> thread); | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     u32 GetIdealCore() const { | 
					
						
							|  |  |  |         return ideal_core; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u64 GetAffinityMask() const { | 
					
						
							|  |  |  |         return affinity_mask; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     ResultCode SetActivity(ThreadActivity value); | 
					
						
							| 
									
										
										
										
											2018-12-03 12:25:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 23:28:29 -04:00
										 |  |  |     /// Sleeps this thread for the given amount of nanoseconds.
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  |     ResultCode Sleep(s64 nanoseconds); | 
					
						
							| 
									
										
										
										
											2019-03-15 23:28:29 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     /// Yields this thread without rebalancing loads.
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  |     ResultCode YieldSimple(); | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Yields this thread and does a load rebalancing.
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  |     ResultCode YieldAndBalanceLoad(); | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Yields this thread and if the core is left idle, loads are rebalanced
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  |     ResultCode YieldAndWaitForLoadBalancing(); | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 12:14:37 -04:00
										 |  |  |     void IncrementYieldCount() { | 
					
						
							|  |  |  |         yield_count++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u64 GetYieldCount() const { | 
					
						
							|  |  |  |         return yield_count; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 09:11:18 -04:00
										 |  |  |     ThreadSchedStatus GetSchedulingStatus() const { | 
					
						
							| 
									
										
										
										
											2019-10-12 10:13:25 -04:00
										 |  |  |         return static_cast<ThreadSchedStatus>(scheduling_state & | 
					
						
							|  |  |  |                                               static_cast<u32>(ThreadSchedMasks::LowMask)); | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-08 11:25:50 -04:00
										 |  |  |     bool IsRunnable() const { | 
					
						
							|  |  |  |         return scheduling_state == static_cast<u32>(ThreadSchedStatus::Runnable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     bool IsRunning() const { | 
					
						
							|  |  |  |         return is_running; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetIsRunning(bool value) { | 
					
						
							|  |  |  |         is_running = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-16 11:05:39 -04:00
										 |  |  |     bool IsSyncCancelled() const { | 
					
						
							|  |  |  |         return is_sync_cancelled; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetSyncCancelled(bool value) { | 
					
						
							|  |  |  |         is_sync_cancelled = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 09:30:53 -04:00
										 |  |  |     Handle GetGlobalHandle() const { | 
					
						
							|  |  |  |         return global_handle; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 17:19:44 -04:00
										 |  |  |     bool IsWaitingForArbitration() const { | 
					
						
							|  |  |  |         return waiting_for_arbitration; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void WaitForArbitration(bool set) { | 
					
						
							|  |  |  |         waiting_for_arbitration = set; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:24:46 -04:00
										 |  |  |     bool IsWaitingSync() const { | 
					
						
							|  |  |  |         return is_waiting_on_sync; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetWaitingSync(bool is_waiting) { | 
					
						
							|  |  |  |         is_waiting_on_sync = is_waiting; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     bool IsPendingTermination() const { | 
					
						
							|  |  |  |         return will_be_terminated || GetSchedulingStatus() == ThreadSchedStatus::Exited; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool IsPaused() const { | 
					
						
							|  |  |  |         return pausing_state != 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     friend class GlobalScheduler; | 
					
						
							|  |  |  |     friend class Scheduler; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     void SetSchedulingStatus(ThreadSchedStatus new_status); | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     void AddSchedulingFlag(ThreadSchedFlags flag); | 
					
						
							|  |  |  |     void RemoveSchedulingFlag(ThreadSchedFlags flag); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     void SetCurrentPriority(u32 new_priority); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core); | 
					
						
							| 
									
										
										
										
											2018-11-13 23:58:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     ThreadContext32 context_32{}; | 
					
						
							|  |  |  |     ThreadContext64 context_64{}; | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     Common::SpinLock context_guard{}; | 
					
						
							|  |  |  |     std::shared_ptr<Common::Fiber> host_context{}; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-18 22:37:01 -05:00
										 |  |  |     u64 thread_id = 0; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ThreadStatus status = ThreadStatus::Dormant; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VAddr entry_point = 0; | 
					
						
							|  |  |  |     VAddr stack_top = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  |     ThreadType type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 21:58:23 -04:00
										 |  |  |     /// Nominal thread priority, as set by the emulated application.
 | 
					
						
							|  |  |  |     /// The nominal priority is the thread priority without priority
 | 
					
						
							|  |  |  |     /// inheritance taken into account.
 | 
					
						
							|  |  |  |     u32 nominal_priority = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Current thread priority. This may change over the course of the
 | 
					
						
							|  |  |  |     /// thread's lifetime in order to facilitate priority inheritance.
 | 
					
						
							|  |  |  |     u32 current_priority = 0; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 18:42:50 -04:00
										 |  |  |     u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks.
 | 
					
						
							|  |  |  |     u64 last_running_ticks = 0;   ///< CPU tick when thread was last running
 | 
					
						
							| 
									
										
										
										
											2019-10-12 10:13:25 -04:00
										 |  |  |     u64 yield_count = 0;          ///< Number of redundant yields carried by this thread.
 | 
					
						
							|  |  |  |                                   ///< a redundant yield is one where no scheduling is changed
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s32 processor_id = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VAddr tls_address = 0; ///< Virtual address of the Thread Local Storage of the thread
 | 
					
						
							|  |  |  |     u64 tpidr_el0 = 0;     ///< TPIDR_EL0 read/write system register.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Process that owns this thread
 | 
					
						
							| 
									
										
										
										
											2018-10-10 00:42:10 -04:00
										 |  |  |     Process* owner_process; | 
					
						
							| 
									
										
										
										
											2016-12-04 09:58:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 10:53:01 -05:00
										 |  |  |     /// Objects that the thread is waiting on, in the same order as they were
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |     /// passed to WaitSynchronization.
 | 
					
						
							| 
									
										
										
										
											2020-03-03 13:37:11 -04:00
										 |  |  |     ThreadSynchronizationObjects* wait_objects; | 
					
						
							| 
									
										
										
										
											2016-12-04 09:58:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 16:38:33 -04:00
										 |  |  |     SynchronizationObject* signaling_object; | 
					
						
							|  |  |  |     ResultCode signaling_result{RESULT_SUCCESS}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-20 20:15:16 -05:00
										 |  |  |     /// List of threads that are waiting for a mutex that is held by this thread.
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     MutexWaitingThreads wait_mutex_threads; | 
					
						
							| 
									
										
										
										
											2018-04-20 20:15:16 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Thread that owns the lock that this thread is waiting for.
 | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  |     std::shared_ptr<Thread> lock_owner; | 
					
						
							| 
									
										
										
										
											2018-04-20 20:15:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /// If waiting on a ConditionVariable, this is the ConditionVariable address
 | 
					
						
							|  |  |  |     VAddr condvar_wait_address = 0; | 
					
						
							|  |  |  |     /// If waiting on a Mutex, this is the mutex address
 | 
					
						
							|  |  |  |     VAddr mutex_wait_address = 0; | 
					
						
							|  |  |  |     /// The handle used to wait for the mutex.
 | 
					
						
							|  |  |  |     Handle wait_handle = 0; | 
					
						
							| 
									
										
										
										
											2018-06-21 04:07:03 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /// If waiting for an AddressArbiter, this is the address being waited on.
 | 
					
						
							| 
									
										
										
										
											2018-06-21 05:13:06 -06:00
										 |  |  |     VAddr arb_wait_address{0}; | 
					
						
							| 
									
										
										
										
											2020-03-03 17:19:44 -04:00
										 |  |  |     bool waiting_for_arbitration{}; | 
					
						
							| 
									
										
										
										
											2016-12-03 22:38:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-07 23:39:37 -04:00
										 |  |  |     /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
 | 
					
						
							| 
									
										
										
										
											2020-02-14 09:30:53 -04:00
										 |  |  |     Handle global_handle = 0; | 
					
						
							| 
									
										
										
										
											2015-06-07 23:39:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
 | 
					
						
							| 
									
										
										
										
											2019-04-17 07:21:19 -04:00
										 |  |  |     /// was waiting via WaitSynchronization then the object will be the last object that became
 | 
					
						
							| 
									
										
										
										
											2020-03-03 13:02:50 -04:00
										 |  |  |     /// available. In case of a timeout, the object will be nullptr. DEPRECATED
 | 
					
						
							|  |  |  |     WakeupCallback wakeup_callback; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Callback for HLE Events
 | 
					
						
							|  |  |  |     HLECallback hle_callback; | 
					
						
							| 
									
										
										
										
											2020-02-25 19:43:28 -04:00
										 |  |  |     Handle hle_time_event; | 
					
						
							| 
									
										
										
										
											2017-09-28 11:53:32 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-05 14:51:16 -04:00
										 |  |  |     Scheduler* scheduler = nullptr; | 
					
						
							| 
									
										
										
										
											2018-05-02 22:36:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-05 23:03:01 -04:00
										 |  |  |     u32 ideal_core{0xFFFFFFFF}; | 
					
						
							| 
									
										
										
										
											2018-05-10 19:12:46 -04:00
										 |  |  |     u64 affinity_mask{0x1}; | 
					
						
							| 
									
										
										
										
											2018-05-05 23:03:01 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     s32 ideal_core_override = -1; | 
					
						
							|  |  |  |     u64 affinity_mask_override = 0x1; | 
					
						
							|  |  |  |     u32 affinity_override_count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 scheduling_state = 0; | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     u32 pausing_state = 0; | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     bool is_running = false; | 
					
						
							| 
									
										
										
										
											2020-03-07 10:24:46 -04:00
										 |  |  |     bool is_waiting_on_sync = false; | 
					
						
							| 
									
										
										
										
											2019-11-16 11:05:39 -04:00
										 |  |  |     bool is_sync_cancelled = false; | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     bool will_be_terminated = false; | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     std::string name; | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Gets the current thread | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | Thread* GetCurrentThread(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:40:49 -05:00
										 |  |  | } // namespace Kernel
 |