| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | // Copyright 2021 yuzu Emulator 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  | #include <array>
 | 
					
						
							| 
									
										
										
										
											2022-04-01 18:57:40 -04:00
										 |  |  | #include <atomic>
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | #include <span>
 | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2020-03-10 13:13:39 -04:00
										 |  |  | #include <utility>
 | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2018-07-31 08:06:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | #include <boost/intrusive/list.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-09 22:11:18 -04:00
										 |  |  | #include "common/common_types.h"
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | #include "common/intrusive_red_black_tree.h"
 | 
					
						
							| 
									
										
										
										
											2022-04-07 16:01:26 -07:00
										 |  |  | #include "common/spin_lock.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-22 00:08:09 -05:00
										 |  |  | #include "core/arm/arm_interface.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-16 21:02:45 -08:00
										 |  |  | #include "core/hle/kernel/k_affinity_mask.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | #include "core/hle/kernel/k_light_lock.h"
 | 
					
						
							| 
									
										
										
										
											2021-02-13 01:29:32 -08:00
										 |  |  | #include "core/hle/kernel/k_spin_lock.h"
 | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  | #include "core/hle/kernel/k_synchronization_object.h"
 | 
					
						
							| 
									
										
										
										
											2022-01-14 16:36:10 -08:00
										 |  |  | #include "core/hle/kernel/k_worker_task.h"
 | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  | #include "core/hle/kernel/slab_helpers.h"
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | #include "core/hle/kernel/svc_common.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | #include "core/hle/kernel/svc_types.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 { | 
					
						
							| 
									
										
										
										
											2020-03-01 12:14:17 -04:00
										 |  |  | class ARM_Interface; | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | 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-12-02 18:08:35 -08:00
										 |  |  | class GlobalSchedulerContext; | 
					
						
							| 
									
										
										
										
											2018-09-13 15:57:45 -04:00
										 |  |  | class KernelCore; | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  | class KProcess; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  | class KScheduler; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | class KThreadQueue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using KThreadFunction = VAddr; | 
					
						
							| 
									
										
										
										
											2018-09-13 15:57:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-01 01:04:30 -08:00
										 |  |  | enum class ThreadType : u32 { | 
					
						
							|  |  |  |     Main = 0, | 
					
						
							|  |  |  |     Kernel = 1, | 
					
						
							|  |  |  |     HighPriority = 2, | 
					
						
							|  |  |  |     User = 3, | 
					
						
							| 
									
										
										
										
											2021-11-26 15:10:21 -08:00
										 |  |  |     Dummy = 100, // Special thread type for emulation purposes only
 | 
					
						
							| 
									
										
										
										
											2014-05-17 00:56:00 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-01-01 01:04:30 -08:00
										 |  |  | DECLARE_ENUM_FLAG_OPERATORS(ThreadType); | 
					
						
							| 
									
										
										
										
											2014-05-17 00:56:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | enum class SuspendType : u32 { | 
					
						
							|  |  |  |     Process = 0, | 
					
						
							|  |  |  |     Thread = 1, | 
					
						
							|  |  |  |     Debug = 2, | 
					
						
							|  |  |  |     Backtrace = 3, | 
					
						
							|  |  |  |     Init = 4, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Count, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-28 13:16:43 -08:00
										 |  |  | enum class ThreadState : u16 { | 
					
						
							|  |  |  |     Initialized = 0, | 
					
						
							|  |  |  |     Waiting = 1, | 
					
						
							|  |  |  |     Runnable = 2, | 
					
						
							|  |  |  |     Terminated = 3, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SuspendShift = 4, | 
					
						
							|  |  |  |     Mask = (1 << SuspendShift) - 1, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ProcessSuspended = (1 << (0 + SuspendShift)), | 
					
						
							|  |  |  |     ThreadSuspended = (1 << (1 + SuspendShift)), | 
					
						
							|  |  |  |     DebugSuspended = (1 << (2 + SuspendShift)), | 
					
						
							|  |  |  |     BacktraceSuspended = (1 << (3 + SuspendShift)), | 
					
						
							|  |  |  |     InitSuspended = (1 << (4 + SuspendShift)), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SuspendFlagMask = ((1 << 5) - 1) << SuspendShift, | 
					
						
							| 
									
										
										
										
											2014-05-22 18:50:36 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-12-28 13:16:43 -08:00
										 |  |  | DECLARE_ENUM_FLAG_OPERATORS(ThreadState); | 
					
						
							| 
									
										
										
										
											2014-05-22 18:50:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | enum class DpcFlag : u32 { | 
					
						
							|  |  |  |     Terminating = (1 << 0), | 
					
						
							|  |  |  |     Terminated = (1 << 1), | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-10 14:29:02 -08:00
										 |  |  | enum class ThreadWaitReasonForDebugging : u32 { | 
					
						
							|  |  |  |     None,            ///< Thread is not waiting
 | 
					
						
							|  |  |  |     Sleep,           ///< Thread is waiting due to a SleepThread SVC
 | 
					
						
							|  |  |  |     IPC,             ///< Thread is waiting for the reply from an IPC request
 | 
					
						
							|  |  |  |     Synchronization, ///< Thread is waiting due to a WaitSynchronization SVC
 | 
					
						
							|  |  |  |     ConditionVar,    ///< Thread is waiting due to a WaitProcessWideKey SVC
 | 
					
						
							|  |  |  |     Arbitration,     ///< Thread is waiting due to a SignalToAddress/WaitForAddress SVC
 | 
					
						
							|  |  |  |     Suspended,       ///< Thread is waiting due to process suspension
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | [[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); | 
					
						
							|  |  |  | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); | 
					
						
							|  |  |  | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 16:36:10 -08:00
										 |  |  | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  |                       public boost::intrusive::list_base_hook<> { | 
					
						
							|  |  |  |     KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     friend class KScheduler; | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |     friend class KProcess; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2021-01-01 02:06:06 -08:00
										 |  |  |     static constexpr s32 DefaultThreadPriority = 44; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     static constexpr s32 IdleThreadPriority = Svc::LowestThreadPriority + 1; | 
					
						
							| 
									
										
										
										
											2022-01-17 18:48:14 -08:00
										 |  |  |     static constexpr s32 DummyThreadPriority = Svc::LowestThreadPriority + 2; | 
					
						
							| 
									
										
										
										
											2021-01-01 02:06:06 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-08 12:11:36 -04:00
										 |  |  |     explicit KThread(KernelCore& kernel_); | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |     ~KThread() override; | 
					
						
							| 
									
										
										
										
											2019-11-24 20:15:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     using ThreadContext32 = Core::ARM_Interface::ThreadContext32; | 
					
						
							|  |  |  |     using ThreadContext64 = Core::ARM_Interface::ThreadContext64; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     using WaiterList = boost::intrusive::list<KThread>; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-15 15:54:25 -04:00
										 |  |  |     void SetName(std::string new_name) { | 
					
						
							|  |  |  |         name = std::move(new_name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Gets the thread's current priority | 
					
						
							|  |  |  |      * @return The current thread's priority | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     [[nodiscard]] s32 GetPriority() const { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         return priority; | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Sets the thread's current priority. | 
					
						
							|  |  |  |      * @param priority The new priority. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void SetPriority(s32 value) { | 
					
						
							|  |  |  |         priority = value; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Gets the thread's nominal priority. | 
					
						
							|  |  |  |      * @return The current thread's nominal priority. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     [[nodiscard]] s32 GetBasePriority() const { | 
					
						
							|  |  |  |         return base_priority; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-25 22:56:17 -08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Gets the thread's thread ID | 
					
						
							|  |  |  |      * @return The thread's ID | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     [[nodiscard]] u64 GetThreadID() const { | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |         return thread_id; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-25 20:34:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void ContinueIfHasKernelWaiters() { | 
					
						
							|  |  |  |         if (GetNumKernelWaiters() > 0) { | 
					
						
							|  |  |  |             Continue(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetBasePriority(s32 value); | 
					
						
							| 
									
										
										
										
											2020-02-25 12:40:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ResultCode Run(); | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void Exit(); | 
					
						
							| 
									
										
										
										
											2019-04-17 07:08:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] u32 GetSuspendFlags() const { | 
					
						
							|  |  |  |         return suspend_allowed_flags & suspend_request_flags; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-25 16:38:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsSuspended() const { | 
					
						
							|  |  |  |         return GetSuspendFlags() != 0; | 
					
						
							| 
									
										
										
										
											2020-02-25 16:38:33 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsSuspendRequested(SuspendType type) const { | 
					
						
							|  |  |  |         return (suspend_request_flags & | 
					
						
							|  |  |  |                 (1u << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type)))) != | 
					
						
							|  |  |  |                0; | 
					
						
							| 
									
										
										
										
											2020-02-25 16:38:33 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-17 02:03:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsSuspendRequested() const { | 
					
						
							|  |  |  |         return suspend_request_flags != 0; | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-03 22:38:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void RequestSuspend(SuspendType type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void Resume(SuspendType type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void TrySuspend(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 16:31:47 -08:00
										 |  |  |     void UpdateState(); | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 16:31:47 -08:00
										 |  |  |     void Continue(); | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-09 19:02:11 -08:00
										 |  |  |     constexpr void SetSyncedIndex(s32 index) { | 
					
						
							|  |  |  |         synced_index = index; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 02:29:53 -08:00
										 |  |  |     [[nodiscard]] constexpr s32 GetSyncedIndex() const { | 
					
						
							| 
									
										
										
										
											2021-11-09 19:02:11 -08:00
										 |  |  |         return synced_index; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constexpr void SetWaitResult(ResultCode wait_res) { | 
					
						
							|  |  |  |         wait_result = wait_res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 02:29:53 -08:00
										 |  |  |     [[nodiscard]] constexpr ResultCode GetWaitResult() const { | 
					
						
							| 
									
										
										
										
											2021-11-09 19:02:11 -08:00
										 |  |  |         return wait_result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] VAddr GetTLSAddress() const { | 
					
						
							| 
									
										
										
										
											2016-09-18 09:38:01 +09:00
										 |  |  |         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. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] u64 GetTPIDR_EL0() const { | 
					
						
							|  |  |  |         return thread_context_64.tpidr; | 
					
						
							| 
									
										
										
										
											2018-07-20 19:57:45 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         thread_context_64.tpidr = value; | 
					
						
							|  |  |  |         thread_context_32.tpidr = static_cast<u32>(value); | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ThreadContext32& GetContext32() { | 
					
						
							|  |  |  |         return thread_context_32; | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] const ThreadContext32& GetContext32() const { | 
					
						
							|  |  |  |         return thread_context_32; | 
					
						
							| 
									
										
										
										
											2020-03-01 23:46:10 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ThreadContext64& GetContext64() { | 
					
						
							|  |  |  |         return thread_context_64; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] const ThreadContext64& GetContext64() const { | 
					
						
							|  |  |  |         return thread_context_64; | 
					
						
							| 
									
										
										
										
											2020-03-12 16:48:43 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-05 17:08:17 -08:00
										 |  |  |     [[nodiscard]] std::shared_ptr<Common::Fiber>& GetHostContext(); | 
					
						
							| 
									
										
										
										
											2020-03-12 16:48:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ThreadState GetState() const { | 
					
						
							| 
									
										
										
										
											2020-12-28 13:16:43 -08:00
										 |  |  |         return thread_state & ThreadState::Mask; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ThreadState GetRawState() const { | 
					
						
							| 
									
										
										
										
											2020-12-28 13:16:43 -08:00
										 |  |  |         return thread_state; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     void SetState(ThreadState state); | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] s64 GetLastScheduledTick() const { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         return last_scheduled_tick; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void SetLastScheduledTick(s64 tick) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         last_scheduled_tick = tick; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void AddCpuTime([[maybe_unused]] s32 core_id_, s64 amount) { | 
					
						
							|  |  |  |         cpu_time += amount; | 
					
						
							|  |  |  |         // TODO(bunnei): Debug kernels track per-core tick counts. Should we?
 | 
					
						
							| 
									
										
										
										
											2018-10-25 18:42:50 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] s64 GetCpuTime() const { | 
					
						
							|  |  |  |         return cpu_time; | 
					
						
							| 
									
										
										
										
											2018-10-25 18:42:50 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] s32 GetActiveCore() const { | 
					
						
							|  |  |  |         return core_id; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void SetActiveCore(s32 core) { | 
					
						
							|  |  |  |         core_id = core; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] s32 GetCurrentCore() const { | 
					
						
							|  |  |  |         return current_core_id; | 
					
						
							| 
									
										
										
										
											2019-03-29 17:01:46 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void SetCurrentCore(s32 core) { | 
					
						
							|  |  |  |         current_core_id = core; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |     [[nodiscard]] KProcess* GetOwnerProcess() { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         return parent; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |     [[nodiscard]] const KProcess* GetOwnerProcess() const { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         return parent; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsUserThread() const { | 
					
						
							|  |  |  |         return parent != nullptr; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:40:38 -08:00
										 |  |  |     u16 GetUserDisableCount() const; | 
					
						
							|  |  |  |     void SetInterruptFlag(); | 
					
						
							|  |  |  |     void ClearInterruptFlag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] KThread* GetLockOwner() const { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         return lock_owner; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |     void SetLockOwner(KThread* owner) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         lock_owner = owner; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] const KAffinityMask& GetAffinityMask() const { | 
					
						
							|  |  |  |         return physical_affinity_mask; | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ResultCode GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] ResultCode GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask); | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-08 12:11:36 -04:00
										 |  |  |     [[nodiscard]] ResultCode SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask); | 
					
						
							| 
									
										
										
										
											2018-12-03 12:25:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ResultCode SetActivity(Svc::ThreadActivity activity); | 
					
						
							| 
									
										
										
										
											2019-03-15 23:28:29 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ResultCode Sleep(s64 timeout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] s64 GetYieldScheduleCount() const { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         return schedule_count; | 
					
						
							| 
									
										
										
										
											2019-09-11 12:14:37 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void SetYieldScheduleCount(s64 count) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         schedule_count = count; | 
					
						
							| 
									
										
										
										
											2019-09-11 12:14:37 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void WaitCancel(); | 
					
						
							| 
									
										
										
										
											2019-11-16 11:05:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsWaitCancelled() const { | 
					
						
							|  |  |  |         return wait_cancelled; | 
					
						
							| 
									
										
										
										
											2019-11-16 11:05:39 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-12 10:17:35 -04:00
										 |  |  |     void ClearWaitCancelled() { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         wait_cancelled = false; | 
					
						
							| 
									
										
										
										
											2020-02-14 09:30:53 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsCancellable() const { | 
					
						
							|  |  |  |         return cancellable; | 
					
						
							| 
									
										
										
										
											2020-03-07 10:24:46 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  |     void SetCancellable() { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         cancellable = true; | 
					
						
							| 
									
										
										
										
											2020-03-07 10:24:46 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  |     void ClearCancellable() { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         cancellable = false; | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool IsTerminationRequested() const { | 
					
						
							|  |  |  |         return termination_requested || GetRawState() == ThreadState::Terminated; | 
					
						
							| 
									
										
										
										
											2020-03-07 12:44:35 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 02:49:07 -04:00
										 |  |  |     [[nodiscard]] u64 GetId() const override { | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  |         return this->GetThreadID(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 02:49:07 -04:00
										 |  |  |     [[nodiscard]] bool IsInitialized() const override { | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  |         return initialized; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 02:49:07 -04:00
										 |  |  |     [[nodiscard]] uintptr_t GetPostDestroyArgument() const override { | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  |         return reinterpret_cast<uintptr_t>(parent) | (resource_limit_release_hint ? 1 : 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 02:49:07 -04:00
										 |  |  |     void Finalize() override; | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 02:49:07 -04:00
										 |  |  |     [[nodiscard]] bool IsSignaled() const override; | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 22:28:30 -08:00
										 |  |  |     void OnTimer(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 16:36:10 -08:00
										 |  |  |     void DoWorkerTaskImpl(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  |     static void PostDestroy(uintptr_t arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] static ResultCode InitializeIdleThread(Core::System& system, KThread* thread, | 
					
						
							|  |  |  |                                                          s32 virt_core); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] static ResultCode InitializeHighPriorityThread(Core::System& system, | 
					
						
							|  |  |  |                                                                  KThread* thread, | 
					
						
							|  |  |  |                                                                  KThreadFunction func, | 
					
						
							|  |  |  |                                                                  uintptr_t arg, s32 virt_core); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] static ResultCode InitializeUserThread(Core::System& system, KThread* thread, | 
					
						
							|  |  |  |                                                          KThreadFunction func, uintptr_t arg, | 
					
						
							|  |  |  |                                                          VAddr user_stack_top, s32 prio, | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |                                                          s32 virt_core, KProcess* owner); | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     struct StackParameters { | 
					
						
							|  |  |  |         u8 svc_permission[0x10]; | 
					
						
							|  |  |  |         std::atomic<u8> dpc_flags; | 
					
						
							|  |  |  |         u8 current_svc_id; | 
					
						
							|  |  |  |         bool is_calling_svc; | 
					
						
							|  |  |  |         bool is_in_exception_handler; | 
					
						
							|  |  |  |         bool is_pinned; | 
					
						
							|  |  |  |         s32 disable_count; | 
					
						
							|  |  |  |         KThread* cur_thread; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-03-10 18:41:11 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] StackParameters& GetStackParameters() { | 
					
						
							|  |  |  |         return stack_parameters; | 
					
						
							| 
									
										
										
										
											2020-03-10 18:41:11 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] const StackParameters& GetStackParameters() const { | 
					
						
							|  |  |  |         return stack_parameters; | 
					
						
							| 
									
										
										
										
											2020-03-07 14:16:25 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  |     class QueueEntry { | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  |         constexpr QueueEntry() = default; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         constexpr void Initialize() { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |             prev = nullptr; | 
					
						
							|  |  |  |             next = nullptr; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |         constexpr KThread* GetPrev() const { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |             return prev; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |         constexpr KThread* GetNext() const { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |             return next; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |         constexpr void SetPrev(KThread* thread) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |             prev = thread; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |         constexpr void SetNext(KThread* thread) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |             next = thread; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |         KThread* prev{}; | 
					
						
							|  |  |  |         KThread* next{}; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] QueueEntry& GetPriorityQueueEntry(s32 core) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         return per_core_priority_queue_entry[core]; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-05 00:17:18 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] const QueueEntry& GetPriorityQueueEntry(s32 core) const { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         return per_core_priority_queue_entry[core]; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 23:04:32 -07:00
										 |  |  |     [[nodiscard]] bool IsKernelThread() const { | 
					
						
							|  |  |  |         return GetActiveCore() == 3; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-14 02:14:19 -07:00
										 |  |  |     [[nodiscard]] bool IsDispatchTrackingDisabled() const { | 
					
						
							|  |  |  |         return is_single_core || IsKernelThread(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] s32 GetDisableDispatchCount() const { | 
					
						
							| 
									
										
										
										
											2021-08-14 02:14:19 -07:00
										 |  |  |         if (IsDispatchTrackingDisabled()) { | 
					
						
							| 
									
										
										
										
											2021-08-06 23:04:32 -07:00
										 |  |  |             // TODO(bunnei): Until kernel threads are emulated, we cannot enable/disable dispatch.
 | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         return this->GetStackParameters().disable_count; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void DisableDispatch() { | 
					
						
							| 
									
										
										
										
											2021-08-14 02:14:19 -07:00
										 |  |  |         if (IsDispatchTrackingDisabled()) { | 
					
						
							| 
									
										
										
										
											2021-08-06 23:04:32 -07:00
										 |  |  |             // TODO(bunnei): Until kernel threads are emulated, we cannot enable/disable dispatch.
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() >= 0); | 
					
						
							|  |  |  |         this->GetStackParameters().disable_count++; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void EnableDispatch() { | 
					
						
							| 
									
										
										
										
											2021-08-14 02:14:19 -07:00
										 |  |  |         if (IsDispatchTrackingDisabled()) { | 
					
						
							| 
									
										
										
										
											2021-08-06 23:04:32 -07:00
										 |  |  |             // TODO(bunnei): Until kernel threads are emulated, we cannot enable/disable dispatch.
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |         ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() > 0); | 
					
						
							|  |  |  |         this->GetStackParameters().disable_count--; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:40:38 -08:00
										 |  |  |     void Pin(s32 current_core); | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void Unpin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetInExceptionHandler() { | 
					
						
							|  |  |  |         this->GetStackParameters().is_in_exception_handler = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ClearInExceptionHandler() { | 
					
						
							|  |  |  |         this->GetStackParameters().is_in_exception_handler = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] bool IsInExceptionHandler() const { | 
					
						
							|  |  |  |         return this->GetStackParameters().is_in_exception_handler; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetIsCallingSvc() { | 
					
						
							|  |  |  |         this->GetStackParameters().is_calling_svc = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ClearIsCallingSvc() { | 
					
						
							|  |  |  |         this->GetStackParameters().is_calling_svc = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] bool IsCallingSvc() const { | 
					
						
							|  |  |  |         return this->GetStackParameters().is_calling_svc; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] u8 GetSvcId() const { | 
					
						
							|  |  |  |         return this->GetStackParameters().current_svc_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void RegisterDpc(DpcFlag flag) { | 
					
						
							|  |  |  |         this->GetStackParameters().dpc_flags |= static_cast<u8>(flag); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ClearDpc(DpcFlag flag) { | 
					
						
							|  |  |  |         this->GetStackParameters().dpc_flags &= ~static_cast<u8>(flag); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] u8 GetDpc() const { | 
					
						
							|  |  |  |         return this->GetStackParameters().dpc_flags; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] bool HasDpc() const { | 
					
						
							|  |  |  |         return this->GetDpc() != 0; | 
					
						
							| 
									
										
										
										
											2020-12-02 18:08:35 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-10 14:29:02 -08:00
										 |  |  |     void SetWaitReasonForDebugging(ThreadWaitReasonForDebugging reason) { | 
					
						
							|  |  |  |         wait_reason_for_debugging = reason; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] ThreadWaitReasonForDebugging GetWaitReasonForDebugging() const { | 
					
						
							|  |  |  |         return wait_reason_for_debugging; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-17 16:41:06 -08:00
										 |  |  |     [[nodiscard]] ThreadType GetThreadType() const { | 
					
						
							|  |  |  |         return thread_type; | 
					
						
							| 
									
										
										
										
											2021-01-24 22:55:08 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 17:10:11 -08:00
										 |  |  |     [[nodiscard]] bool IsDummyThread() const { | 
					
						
							|  |  |  |         return GetThreadType() == ThreadType::Dummy; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     void SetWaitObjectsForDebugging(const std::span<KSynchronizationObject*>& objects) { | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  |         wait_objects_for_debugging.clear(); | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         wait_objects_for_debugging.reserve(objects.size()); | 
					
						
							|  |  |  |         for (const auto& object : objects) { | 
					
						
							|  |  |  |             wait_objects_for_debugging.emplace_back(object); | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     [[nodiscard]] const std::vector<KSynchronizationObject*>& GetWaitObjectsForDebugging() const { | 
					
						
							| 
									
										
										
										
											2020-12-21 22:36:53 -08:00
										 |  |  |         return wait_objects_for_debugging; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     void SetMutexWaitAddressForDebugging(VAddr address) { | 
					
						
							|  |  |  |         mutex_wait_address_for_debugging = address; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] VAddr GetMutexWaitAddressForDebugging() const { | 
					
						
							|  |  |  |         return mutex_wait_address_for_debugging; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] s32 GetIdealCoreForDebugging() const { | 
					
						
							|  |  |  |         return virtual_ideal_core_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |     void AddWaiter(KThread* thread); | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |     void RemoveWaiter(KThread* thread); | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ResultCode GetThreadContext3(std::vector<u8>& out); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |     [[nodiscard]] KThread* RemoveWaiterByKey(s32* out_num_waiters, VAddr key); | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] VAddr GetAddressKey() const { | 
					
						
							|  |  |  |         return address_key; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] u32 GetAddressKeyValue() const { | 
					
						
							|  |  |  |         return address_key_value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetAddressKey(VAddr key) { | 
					
						
							|  |  |  |         address_key = key; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SetAddressKey(VAddr key, u32 val) { | 
					
						
							|  |  |  |         address_key = key; | 
					
						
							|  |  |  |         address_key_value = val; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-09 19:02:11 -08:00
										 |  |  |     void ClearWaitQueue() { | 
					
						
							| 
									
										
										
										
											2021-11-28 00:40:25 -08:00
										 |  |  |         wait_queue = nullptr; | 
					
						
							| 
									
										
										
										
											2021-11-09 19:02:11 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void BeginWait(KThreadQueue* queue); | 
					
						
							|  |  |  |     void NotifyAvailable(KSynchronizationObject* signaled_object, ResultCode wait_result_); | 
					
						
							|  |  |  |     void EndWait(ResultCode wait_result_); | 
					
						
							|  |  |  |     void CancelWait(ResultCode wait_result_, bool cancel_timer_task); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] bool HasWaiters() const { | 
					
						
							|  |  |  |         return !waiter_list.empty(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] s32 GetNumKernelWaiters() const { | 
					
						
							|  |  |  |         return num_kernel_waiters; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] u64 GetConditionVariableKey() const { | 
					
						
							|  |  |  |         return condvar_key; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] u64 GetAddressArbiterKey() const { | 
					
						
							|  |  |  |         return condvar_key; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 17:10:11 -08:00
										 |  |  |     // Dummy threads (used for HLE host threads) cannot wait based on the guest scheduler, and
 | 
					
						
							|  |  |  |     // therefore will not block on guest kernel synchronization primitives. These methods handle
 | 
					
						
							|  |  |  |     // blocking as needed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void IfDummyThreadTryWait(); | 
					
						
							|  |  |  |     void IfDummyThreadBeginWait(); | 
					
						
							|  |  |  |     void IfDummyThreadEndWait(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 18:47:57 -04:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     static constexpr size_t PriorityInheritanceCountMax = 10; | 
					
						
							|  |  |  |     union SyncObjectBuffer { | 
					
						
							|  |  |  |         std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{}; | 
					
						
							|  |  |  |         std::array<Handle, | 
					
						
							|  |  |  |                    Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))> | 
					
						
							|  |  |  |             handles; | 
					
						
							|  |  |  |         constexpr SyncObjectBuffer() {} | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct ConditionVariableComparator { | 
					
						
							| 
									
										
										
										
											2022-03-10 23:58:00 -08:00
										 |  |  |         struct RedBlackKeyType { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |             u64 cv_key{}; | 
					
						
							|  |  |  |             s32 priority{}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             [[nodiscard]] constexpr u64 GetConditionVariableKey() const { | 
					
						
							|  |  |  |                 return cv_key; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             [[nodiscard]] constexpr s32 GetPriority() const { | 
					
						
							|  |  |  |                 return priority; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         template <typename T> | 
					
						
							|  |  |  |         requires( | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |             std::same_as<T, KThread> || | 
					
						
							| 
									
										
										
										
											2022-03-10 23:58:00 -08:00
										 |  |  |             std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs, | 
					
						
							|  |  |  |                                                                            const KThread& rhs) { | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |             const u64 l_key = lhs.GetConditionVariableKey(); | 
					
						
							|  |  |  |             const u64 r_key = rhs.GetConditionVariableKey(); | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (l_key < r_key) { | 
					
						
							|  |  |  |                 // Sort first by key
 | 
					
						
							|  |  |  |                 return -1; | 
					
						
							|  |  |  |             } else if (l_key == r_key && lhs.GetPriority() < rhs.GetPriority()) { | 
					
						
							|  |  |  |                 // And then by priority.
 | 
					
						
							|  |  |  |                 return -1; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 return 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void AddWaiterImpl(KThread* thread); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void RemoveWaiterImpl(KThread* thread); | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void StartTermination(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 16:36:10 -08:00
										 |  |  |     void FinishTermination(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     [[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |                                         s32 prio, s32 virt_core, KProcess* owner, ThreadType type); | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] static ResultCode InitializeThread(KThread* thread, KThreadFunction func, | 
					
						
							|  |  |  |                                                      uintptr_t arg, VAddr user_stack_top, s32 prio, | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |                                                      s32 core, KProcess* owner, ThreadType type, | 
					
						
							| 
									
										
										
										
											2021-04-02 23:24:20 -07:00
										 |  |  |                                                      std::function<void(void*)>&& init_func, | 
					
						
							|  |  |  |                                                      void* init_func_parameter); | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-08 12:11:36 -04:00
										 |  |  |     static void RestorePriority(KernelCore& kernel_ctx, KThread* thread); | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // For core KThread implementation
 | 
					
						
							|  |  |  |     ThreadContext32 thread_context_32{}; | 
					
						
							|  |  |  |     ThreadContext64 thread_context_64{}; | 
					
						
							|  |  |  |     Common::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node{}; | 
					
						
							|  |  |  |     s32 priority{}; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     using ConditionVariableThreadTreeTraits = | 
					
						
							| 
									
										
										
										
											2020-12-30 23:01:08 -08:00
										 |  |  |         Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert< | 
					
						
							|  |  |  |             &KThread::condvar_arbiter_tree_node>; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |     using ConditionVariableThreadTree = | 
					
						
							|  |  |  |         ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     ConditionVariableThreadTree* condvar_tree{}; | 
					
						
							|  |  |  |     u64 condvar_key{}; | 
					
						
							|  |  |  |     u64 virtual_affinity_mask{}; | 
					
						
							|  |  |  |     KAffinityMask physical_affinity_mask{}; | 
					
						
							|  |  |  |     u64 thread_id{}; | 
					
						
							|  |  |  |     std::atomic<s64> cpu_time{}; | 
					
						
							|  |  |  |     VAddr address_key{}; | 
					
						
							| 
									
										
										
										
											2021-04-23 22:04:28 -07:00
										 |  |  |     KProcess* parent{}; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     VAddr kernel_stack_top{}; | 
					
						
							|  |  |  |     u32* light_ipc_data{}; | 
					
						
							|  |  |  |     VAddr tls_address{}; | 
					
						
							|  |  |  |     KLightLock activity_pause_lock; | 
					
						
							|  |  |  |     s64 schedule_count{}; | 
					
						
							|  |  |  |     s64 last_scheduled_tick{}; | 
					
						
							|  |  |  |     std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{}; | 
					
						
							| 
									
										
										
										
											2021-11-28 00:40:25 -08:00
										 |  |  |     KThreadQueue* wait_queue{}; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     WaiterList waiter_list{}; | 
					
						
							|  |  |  |     WaiterList pinned_waiter_list{}; | 
					
						
							|  |  |  |     KThread* lock_owner{}; | 
					
						
							|  |  |  |     u32 address_key_value{}; | 
					
						
							|  |  |  |     u32 suspend_request_flags{}; | 
					
						
							|  |  |  |     u32 suspend_allowed_flags{}; | 
					
						
							| 
									
										
										
										
											2021-11-09 19:02:11 -08:00
										 |  |  |     s32 synced_index{}; | 
					
						
							| 
									
										
										
										
											2021-05-21 01:05:04 -04:00
										 |  |  |     ResultCode wait_result{ResultSuccess}; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     s32 base_priority{}; | 
					
						
							|  |  |  |     s32 physical_ideal_core_id{}; | 
					
						
							|  |  |  |     s32 virtual_ideal_core_id{}; | 
					
						
							|  |  |  |     s32 num_kernel_waiters{}; | 
					
						
							|  |  |  |     s32 current_core_id{}; | 
					
						
							|  |  |  |     s32 core_id{}; | 
					
						
							|  |  |  |     KAffinityMask original_physical_affinity_mask{}; | 
					
						
							|  |  |  |     s32 original_physical_ideal_core_id{}; | 
					
						
							|  |  |  |     s32 num_core_migration_disables{}; | 
					
						
							| 
									
										
										
										
											2022-04-01 18:57:40 -04:00
										 |  |  |     std::atomic<ThreadState> thread_state{}; | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     std::atomic<bool> termination_requested{}; | 
					
						
							|  |  |  |     bool wait_cancelled{}; | 
					
						
							|  |  |  |     bool cancellable{}; | 
					
						
							|  |  |  |     bool signaled{}; | 
					
						
							|  |  |  |     bool initialized{}; | 
					
						
							|  |  |  |     bool debug_attached{}; | 
					
						
							|  |  |  |     s8 priority_inheritance_count{}; | 
					
						
							|  |  |  |     bool resource_limit_release_hint{}; | 
					
						
							|  |  |  |     StackParameters stack_parameters{}; | 
					
						
							| 
									
										
										
										
											2022-04-07 16:01:26 -07:00
										 |  |  |     Common::SpinLock context_guard{}; | 
					
						
							| 
									
										
										
										
											2022-01-21 17:10:11 -08:00
										 |  |  |     KSpinLock dummy_wait_lock{}; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     // For emulation
 | 
					
						
							| 
									
										
										
										
											2021-03-05 17:08:17 -08:00
										 |  |  |     std::shared_ptr<Common::Fiber> host_context{}; | 
					
						
							| 
									
										
										
										
											2021-08-14 02:14:19 -07:00
										 |  |  |     bool is_single_core{}; | 
					
						
							| 
									
										
										
										
											2022-01-17 16:41:06 -08:00
										 |  |  |     ThreadType thread_type{}; | 
					
						
							| 
									
										
										
										
											2020-02-24 22:04:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     // For debugging
 | 
					
						
							|  |  |  |     std::vector<KSynchronizationObject*> wait_objects_for_debugging; | 
					
						
							|  |  |  |     VAddr mutex_wait_address_for_debugging{}; | 
					
						
							|  |  |  |     ThreadWaitReasonForDebugging wait_reason_for_debugging{}; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  | public: | 
					
						
							|  |  |  |     using ConditionVariableThreadTreeType = ConditionVariableThreadTree; | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, u64 cv_key, | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |                               u32 value) { | 
					
						
							|  |  |  |         condvar_tree = tree; | 
					
						
							|  |  |  |         condvar_key = cv_key; | 
					
						
							|  |  |  |         address_key = address; | 
					
						
							|  |  |  |         address_key_value = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ClearConditionVariable() { | 
					
						
							|  |  |  |         condvar_tree = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] bool IsWaitingForConditionVariable() const { | 
					
						
							|  |  |  |         return condvar_tree != nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-20 13:42:27 -08:00
										 |  |  |     void SetAddressArbiter(ConditionVariableThreadTree* tree, u64 address) { | 
					
						
							| 
									
										
										
										
											2020-12-30 01:14:02 -08:00
										 |  |  |         condvar_tree = tree; | 
					
						
							|  |  |  |         condvar_key = address; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ClearAddressArbiter() { | 
					
						
							|  |  |  |         condvar_tree = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] bool IsWaitingForAddressArbiter() const { | 
					
						
							|  |  |  |         return condvar_tree != nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] ConditionVariableThreadTree* GetConditionVariableTree() const { | 
					
						
							|  |  |  |         return condvar_tree; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-22 04:32:03 -02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 23:04:32 -07:00
										 |  |  | class KScopedDisableDispatch { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2021-08-07 12:33:31 -07:00
										 |  |  |     [[nodiscard]] explicit KScopedDisableDispatch(KernelCore& kernel_) : kernel{kernel_} { | 
					
						
							| 
									
										
										
										
											2021-11-25 20:46:17 -08:00
										 |  |  |         // If we are shutting down the kernel, none of this is relevant anymore.
 | 
					
						
							|  |  |  |         if (kernel.IsShuttingDown()) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-08-06 23:04:32 -07:00
										 |  |  |         GetCurrentThread(kernel).DisableDispatch(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ~KScopedDisableDispatch(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     KernelCore& kernel; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:40:49 -05:00
										 |  |  | } // namespace Kernel
 |