thread.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. // Copyright 2014 Citra Emulator Project / PPSSPP Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <functional>
  7. #include <span>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include <boost/intrusive/list.hpp>
  12. #include "common/common_types.h"
  13. #include "common/intrusive_red_black_tree.h"
  14. #include "common/spin_lock.h"
  15. #include "core/arm/arm_interface.h"
  16. #include "core/hle/kernel/k_affinity_mask.h"
  17. #include "core/hle/kernel/k_synchronization_object.h"
  18. #include "core/hle/kernel/object.h"
  19. #include "core/hle/kernel/svc_common.h"
  20. #include "core/hle/result.h"
  21. namespace Common {
  22. class Fiber;
  23. }
  24. namespace Core {
  25. class ARM_Interface;
  26. class System;
  27. } // namespace Core
  28. namespace Kernel {
  29. class GlobalSchedulerContext;
  30. class KernelCore;
  31. class Process;
  32. class KScheduler;
  33. enum ThreadPriority : u32 {
  34. THREADPRIO_HIGHEST = 0, ///< Highest thread priority
  35. THREADPRIO_MAX_CORE_MIGRATION = 2, ///< Highest priority for a core migration
  36. THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps
  37. THREADPRIO_DEFAULT = 44, ///< Default thread priority for userland apps
  38. THREADPRIO_LOWEST = 63, ///< Lowest thread priority
  39. THREADPRIO_COUNT = 64, ///< Total number of possible thread priorities.
  40. };
  41. enum ThreadType : u32 {
  42. THREADTYPE_USER = 0x1,
  43. THREADTYPE_KERNEL = 0x2,
  44. THREADTYPE_HLE = 0x4,
  45. THREADTYPE_IDLE = 0x8,
  46. THREADTYPE_SUSPEND = 0x10,
  47. };
  48. enum ThreadProcessorId : s32 {
  49. /// Indicates that no particular processor core is preferred.
  50. THREADPROCESSORID_DONT_CARE = -1,
  51. /// Run thread on the ideal core specified by the process.
  52. THREADPROCESSORID_IDEAL = -2,
  53. /// Indicates that the preferred processor ID shouldn't be updated in
  54. /// a core mask setting operation.
  55. THREADPROCESSORID_DONT_UPDATE = -3,
  56. THREADPROCESSORID_0 = 0, ///< Run thread on core 0
  57. THREADPROCESSORID_1 = 1, ///< Run thread on core 1
  58. THREADPROCESSORID_2 = 2, ///< Run thread on core 2
  59. THREADPROCESSORID_3 = 3, ///< Run thread on core 3
  60. THREADPROCESSORID_MAX = 4, ///< Processor ID must be less than this
  61. /// Allowed CPU mask
  62. THREADPROCESSORID_DEFAULT_MASK = (1 << THREADPROCESSORID_0) | (1 << THREADPROCESSORID_1) |
  63. (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3)
  64. };
  65. enum class ThreadState : u16 {
  66. Initialized = 0,
  67. Waiting = 1,
  68. Runnable = 2,
  69. Terminated = 3,
  70. SuspendShift = 4,
  71. Mask = (1 << SuspendShift) - 1,
  72. ProcessSuspended = (1 << (0 + SuspendShift)),
  73. ThreadSuspended = (1 << (1 + SuspendShift)),
  74. DebugSuspended = (1 << (2 + SuspendShift)),
  75. BacktraceSuspended = (1 << (3 + SuspendShift)),
  76. InitSuspended = (1 << (4 + SuspendShift)),
  77. SuspendFlagMask = ((1 << 5) - 1) << SuspendShift,
  78. };
  79. DECLARE_ENUM_FLAG_OPERATORS(ThreadState);
  80. enum class ThreadWakeupReason {
  81. Signal, // The thread was woken up by WakeupAllWaitingThreads due to an object signal.
  82. Timeout // The thread was woken up due to a wait timeout.
  83. };
  84. enum class ThreadActivity : u32 {
  85. Normal = 0,
  86. Paused = 1,
  87. };
  88. enum class ThreadSchedFlags : u32 {
  89. ProcessPauseFlag = 1 << 4,
  90. ThreadPauseFlag = 1 << 5,
  91. ProcessDebugPauseFlag = 1 << 6,
  92. KernelInitPauseFlag = 1 << 8,
  93. };
  94. class Thread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> {
  95. friend class KScheduler;
  96. friend class Process;
  97. public:
  98. explicit Thread(KernelCore& kernel);
  99. ~Thread() override;
  100. using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>;
  101. using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
  102. using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
  103. /**
  104. * Creates and returns a new thread. The new thread is immediately scheduled
  105. * @param system The instance of the whole system
  106. * @param name The friendly name desired for the thread
  107. * @param entry_point The address at which the thread should start execution
  108. * @param priority The thread's priority
  109. * @param arg User data to pass to the thread
  110. * @param processor_id The ID(s) of the processors on which the thread is desired to be run
  111. * @param stack_top The address of the thread's stack top
  112. * @param owner_process The parent process for the thread, if null, it's a kernel thread
  113. * @return A shared pointer to the newly created thread
  114. */
  115. static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags,
  116. std::string name, VAddr entry_point,
  117. u32 priority, u64 arg, s32 processor_id,
  118. VAddr stack_top, Process* owner_process);
  119. /**
  120. * Creates and returns a new thread. The new thread is immediately scheduled
  121. * @param system The instance of the whole system
  122. * @param name The friendly name desired for the thread
  123. * @param entry_point The address at which the thread should start execution
  124. * @param priority The thread's priority
  125. * @param arg User data to pass to the thread
  126. * @param processor_id The ID(s) of the processors on which the thread is desired to be run
  127. * @param stack_top The address of the thread's stack top
  128. * @param owner_process The parent process for the thread, if null, it's a kernel thread
  129. * @param thread_start_func The function where the host context will start.
  130. * @param thread_start_parameter The parameter which will passed to host context on init
  131. * @return A shared pointer to the newly created thread
  132. */
  133. static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags,
  134. std::string name, VAddr entry_point,
  135. u32 priority, u64 arg, s32 processor_id,
  136. VAddr stack_top, Process* owner_process,
  137. std::function<void(void*)>&& thread_start_func,
  138. void* thread_start_parameter);
  139. std::string GetName() const override {
  140. return name;
  141. }
  142. void SetName(std::string new_name) {
  143. name = std::move(new_name);
  144. }
  145. std::string GetTypeName() const override {
  146. return "Thread";
  147. }
  148. static constexpr HandleType HANDLE_TYPE = HandleType::Thread;
  149. HandleType GetHandleType() const override {
  150. return HANDLE_TYPE;
  151. }
  152. /**
  153. * Gets the thread's current priority
  154. * @return The current thread's priority
  155. */
  156. [[nodiscard]] s32 GetPriority() const {
  157. return current_priority;
  158. }
  159. /**
  160. * Sets the thread's current priority.
  161. * @param priority The new priority.
  162. */
  163. void SetPriority(s32 priority) {
  164. current_priority = priority;
  165. }
  166. /**
  167. * Gets the thread's nominal priority.
  168. * @return The current thread's nominal priority.
  169. */
  170. [[nodiscard]] s32 GetBasePriority() const {
  171. return base_priority;
  172. }
  173. /**
  174. * Sets the thread's nominal priority.
  175. * @param priority The new priority.
  176. */
  177. void SetBasePriority(u32 priority);
  178. /// Changes the core that the thread is running or scheduled to run on.
  179. [[nodiscard]] ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
  180. /**
  181. * Gets the thread's thread ID
  182. * @return The thread's ID
  183. */
  184. [[nodiscard]] u64 GetThreadID() const {
  185. return thread_id;
  186. }
  187. /// Resumes a thread from waiting
  188. void Wakeup();
  189. ResultCode Start();
  190. virtual bool IsSignaled() const override;
  191. /// Cancels a waiting operation that this thread may or may not be within.
  192. ///
  193. /// When the thread is within a waiting state, this will set the thread's
  194. /// waiting result to signal a canceled wait. The function will then resume
  195. /// this thread.
  196. ///
  197. void CancelWait();
  198. void SetSynchronizationResults(KSynchronizationObject* object, ResultCode result);
  199. void SetSyncedObject(KSynchronizationObject* object, ResultCode result) {
  200. SetSynchronizationResults(object, result);
  201. }
  202. ResultCode GetWaitResult(KSynchronizationObject** out) const {
  203. *out = signaling_object;
  204. return signaling_result;
  205. }
  206. ResultCode GetSignalingResult() const {
  207. return signaling_result;
  208. }
  209. /**
  210. * Stops a thread, invalidating it from further use
  211. */
  212. void Stop();
  213. /*
  214. * Returns the Thread Local Storage address of the current thread
  215. * @returns VAddr of the thread's TLS
  216. */
  217. VAddr GetTLSAddress() const {
  218. return tls_address;
  219. }
  220. /*
  221. * Returns the value of the TPIDR_EL0 Read/Write system register for this thread.
  222. * @returns The value of the TPIDR_EL0 register.
  223. */
  224. u64 GetTPIDR_EL0() const {
  225. return tpidr_el0;
  226. }
  227. /// Sets the value of the TPIDR_EL0 Read/Write system register for this thread.
  228. void SetTPIDR_EL0(u64 value) {
  229. tpidr_el0 = value;
  230. }
  231. /*
  232. * Returns the address of the current thread's command buffer, located in the TLS.
  233. * @returns VAddr of the thread's command buffer.
  234. */
  235. VAddr GetCommandBufferAddress() const;
  236. ThreadContext32& GetContext32() {
  237. return context_32;
  238. }
  239. const ThreadContext32& GetContext32() const {
  240. return context_32;
  241. }
  242. ThreadContext64& GetContext64() {
  243. return context_64;
  244. }
  245. const ThreadContext64& GetContext64() const {
  246. return context_64;
  247. }
  248. bool IsHLEThread() const {
  249. return (type & THREADTYPE_HLE) != 0;
  250. }
  251. bool IsSuspendThread() const {
  252. return (type & THREADTYPE_SUSPEND) != 0;
  253. }
  254. bool IsIdleThread() const {
  255. return (type & THREADTYPE_IDLE) != 0;
  256. }
  257. bool WasRunning() const {
  258. return was_running;
  259. }
  260. void SetWasRunning(bool value) {
  261. was_running = value;
  262. }
  263. std::shared_ptr<Common::Fiber>& GetHostContext();
  264. ThreadState GetState() const {
  265. return thread_state & ThreadState::Mask;
  266. }
  267. ThreadState GetRawState() const {
  268. return thread_state;
  269. }
  270. void SetState(ThreadState state);
  271. s64 GetLastScheduledTick() const {
  272. return last_scheduled_tick;
  273. }
  274. void SetLastScheduledTick(s64 tick) {
  275. last_scheduled_tick = tick;
  276. }
  277. u64 GetTotalCPUTimeTicks() const {
  278. return total_cpu_time_ticks;
  279. }
  280. void UpdateCPUTimeTicks(u64 ticks) {
  281. total_cpu_time_ticks += ticks;
  282. }
  283. s32 GetProcessorID() const {
  284. return processor_id;
  285. }
  286. s32 GetActiveCore() const {
  287. return GetProcessorID();
  288. }
  289. void SetProcessorID(s32 new_core) {
  290. processor_id = new_core;
  291. }
  292. void SetActiveCore(s32 new_core) {
  293. processor_id = new_core;
  294. }
  295. Process* GetOwnerProcess() {
  296. return owner_process;
  297. }
  298. const Process* GetOwnerProcess() const {
  299. return owner_process;
  300. }
  301. const MutexWaitingThreads& GetMutexWaitingThreads() const {
  302. return wait_mutex_threads;
  303. }
  304. Thread* GetLockOwner() const {
  305. return lock_owner;
  306. }
  307. void SetLockOwner(Thread* owner) {
  308. lock_owner = owner;
  309. }
  310. u32 GetIdealCore() const {
  311. return ideal_core;
  312. }
  313. const KAffinityMask& GetAffinityMask() const {
  314. return affinity_mask;
  315. }
  316. ResultCode SetActivity(ThreadActivity value);
  317. /// Sleeps this thread for the given amount of nanoseconds.
  318. ResultCode Sleep(s64 nanoseconds);
  319. s64 GetYieldScheduleCount() const {
  320. return schedule_count;
  321. }
  322. void SetYieldScheduleCount(s64 count) {
  323. schedule_count = count;
  324. }
  325. bool IsRunning() const {
  326. return is_running;
  327. }
  328. void SetIsRunning(bool value) {
  329. is_running = value;
  330. }
  331. bool IsWaitCancelled() const {
  332. return is_sync_cancelled;
  333. }
  334. void ClearWaitCancelled() {
  335. is_sync_cancelled = false;
  336. }
  337. Handle GetGlobalHandle() const {
  338. return global_handle;
  339. }
  340. bool IsCancellable() const {
  341. return is_cancellable;
  342. }
  343. void SetCancellable() {
  344. is_cancellable = true;
  345. }
  346. void ClearCancellable() {
  347. is_cancellable = false;
  348. }
  349. bool IsTerminationRequested() const {
  350. return will_be_terminated || GetRawState() == ThreadState::Terminated;
  351. }
  352. bool IsPaused() const {
  353. return pausing_state != 0;
  354. }
  355. bool IsContinuousOnSVC() const {
  356. return is_continuous_on_svc;
  357. }
  358. void SetContinuousOnSVC(bool is_continuous) {
  359. is_continuous_on_svc = is_continuous;
  360. }
  361. bool IsPhantomMode() const {
  362. return is_phantom_mode;
  363. }
  364. void SetPhantomMode(bool phantom) {
  365. is_phantom_mode = phantom;
  366. }
  367. bool HasExited() const {
  368. return has_exited;
  369. }
  370. class QueueEntry {
  371. public:
  372. constexpr QueueEntry() = default;
  373. constexpr void Initialize() {
  374. prev = nullptr;
  375. next = nullptr;
  376. }
  377. constexpr Thread* GetPrev() const {
  378. return prev;
  379. }
  380. constexpr Thread* GetNext() const {
  381. return next;
  382. }
  383. constexpr void SetPrev(Thread* thread) {
  384. prev = thread;
  385. }
  386. constexpr void SetNext(Thread* thread) {
  387. next = thread;
  388. }
  389. private:
  390. Thread* prev{};
  391. Thread* next{};
  392. };
  393. QueueEntry& GetPriorityQueueEntry(s32 core) {
  394. return per_core_priority_queue_entry[core];
  395. }
  396. const QueueEntry& GetPriorityQueueEntry(s32 core) const {
  397. return per_core_priority_queue_entry[core];
  398. }
  399. s32 GetDisableDispatchCount() const {
  400. return disable_count;
  401. }
  402. void DisableDispatch() {
  403. ASSERT(GetDisableDispatchCount() >= 0);
  404. disable_count++;
  405. }
  406. void EnableDispatch() {
  407. ASSERT(GetDisableDispatchCount() > 0);
  408. disable_count--;
  409. }
  410. void SetWaitObjectsForDebugging(const std::span<KSynchronizationObject*>& objects) {
  411. wait_objects_for_debugging.clear();
  412. wait_objects_for_debugging.reserve(objects.size());
  413. for (const auto& object : objects) {
  414. wait_objects_for_debugging.emplace_back(object);
  415. }
  416. }
  417. [[nodiscard]] const std::vector<KSynchronizationObject*>& GetWaitObjectsForDebugging() const {
  418. return wait_objects_for_debugging;
  419. }
  420. void SetMutexWaitAddressForDebugging(VAddr address) {
  421. mutex_wait_address_for_debugging = address;
  422. }
  423. [[nodiscard]] VAddr GetMutexWaitAddressForDebugging() const {
  424. return mutex_wait_address_for_debugging;
  425. }
  426. void AddWaiter(Thread* thread);
  427. void RemoveWaiter(Thread* thread);
  428. [[nodiscard]] Thread* RemoveWaiterByKey(s32* out_num_waiters, VAddr key);
  429. [[nodiscard]] VAddr GetAddressKey() const {
  430. return address_key;
  431. }
  432. [[nodiscard]] u32 GetAddressKeyValue() const {
  433. return address_key_value;
  434. }
  435. void SetAddressKey(VAddr key) {
  436. address_key = key;
  437. }
  438. void SetAddressKey(VAddr key, u32 val) {
  439. address_key = key;
  440. address_key_value = val;
  441. }
  442. private:
  443. static constexpr size_t PriorityInheritanceCountMax = 10;
  444. union SyncObjectBuffer {
  445. std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
  446. std::array<Handle,
  447. Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))>
  448. handles;
  449. constexpr SyncObjectBuffer() {}
  450. };
  451. static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles));
  452. struct ConditionVariableComparator {
  453. struct LightCompareType {
  454. u64 cv_key{};
  455. s32 priority{};
  456. [[nodiscard]] constexpr u64 GetConditionVariableKey() const {
  457. return cv_key;
  458. }
  459. [[nodiscard]] constexpr s32 GetPriority() const {
  460. return priority;
  461. }
  462. };
  463. template <typename T>
  464. requires(
  465. std::same_as<T, Thread> ||
  466. std::same_as<T, LightCompareType>) static constexpr int Compare(const T& lhs,
  467. const Thread& rhs) {
  468. const uintptr_t l_key = lhs.GetConditionVariableKey();
  469. const uintptr_t r_key = rhs.GetConditionVariableKey();
  470. if (l_key < r_key) {
  471. // Sort first by key
  472. return -1;
  473. } else if (l_key == r_key && lhs.GetPriority() < rhs.GetPriority()) {
  474. // And then by priority.
  475. return -1;
  476. } else {
  477. return 1;
  478. }
  479. }
  480. };
  481. Common::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node{};
  482. using ConditionVariableThreadTreeTraits =
  483. Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&Thread::condvar_arbiter_tree_node>;
  484. using ConditionVariableThreadTree =
  485. ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
  486. public:
  487. using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
  488. [[nodiscard]] uintptr_t GetConditionVariableKey() const {
  489. return condvar_key;
  490. }
  491. [[nodiscard]] uintptr_t GetAddressArbiterKey() const {
  492. return condvar_key;
  493. }
  494. void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, uintptr_t cv_key,
  495. u32 value) {
  496. condvar_tree = tree;
  497. condvar_key = cv_key;
  498. address_key = address;
  499. address_key_value = value;
  500. }
  501. void ClearConditionVariable() {
  502. condvar_tree = nullptr;
  503. }
  504. [[nodiscard]] bool IsWaitingForConditionVariable() const {
  505. return condvar_tree != nullptr;
  506. }
  507. void SetAddressArbiter(ConditionVariableThreadTree* tree, uintptr_t address) {
  508. condvar_tree = tree;
  509. condvar_key = address;
  510. }
  511. void ClearAddressArbiter() {
  512. condvar_tree = nullptr;
  513. }
  514. [[nodiscard]] bool IsWaitingForAddressArbiter() const {
  515. return condvar_tree != nullptr;
  516. }
  517. [[nodiscard]] ConditionVariableThreadTree* GetConditionVariableTree() const {
  518. return condvar_tree;
  519. }
  520. [[nodiscard]] bool HasWaiters() const {
  521. return !waiter_list.empty();
  522. }
  523. private:
  524. void AddSchedulingFlag(ThreadSchedFlags flag);
  525. void RemoveSchedulingFlag(ThreadSchedFlags flag);
  526. void AddWaiterImpl(Thread* thread);
  527. void RemoveWaiterImpl(Thread* thread);
  528. static void RestorePriority(KernelCore& kernel, Thread* thread);
  529. Common::SpinLock context_guard{};
  530. ThreadContext32 context_32{};
  531. ThreadContext64 context_64{};
  532. std::shared_ptr<Common::Fiber> host_context{};
  533. ThreadState thread_state = ThreadState::Initialized;
  534. u64 thread_id = 0;
  535. VAddr entry_point = 0;
  536. VAddr stack_top = 0;
  537. std::atomic_int disable_count = 0;
  538. ThreadType type;
  539. /// Nominal thread priority, as set by the emulated application.
  540. /// The nominal priority is the thread priority without priority
  541. /// inheritance taken into account.
  542. s32 base_priority{};
  543. /// Current thread priority. This may change over the course of the
  544. /// thread's lifetime in order to facilitate priority inheritance.
  545. s32 current_priority{};
  546. u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks.
  547. s64 schedule_count{};
  548. s64 last_scheduled_tick{};
  549. s32 processor_id = 0;
  550. VAddr tls_address = 0; ///< Virtual address of the Thread Local Storage of the thread
  551. u64 tpidr_el0 = 0; ///< TPIDR_EL0 read/write system register.
  552. /// Process that owns this thread
  553. Process* owner_process;
  554. /// Objects that the thread is waiting on, in the same order as they were
  555. /// passed to WaitSynchronization. This is used for debugging only.
  556. std::vector<KSynchronizationObject*> wait_objects_for_debugging;
  557. /// The current mutex wait address. This is used for debugging only.
  558. VAddr mutex_wait_address_for_debugging{};
  559. KSynchronizationObject* signaling_object;
  560. ResultCode signaling_result{RESULT_SUCCESS};
  561. /// List of threads that are waiting for a mutex that is held by this thread.
  562. MutexWaitingThreads wait_mutex_threads;
  563. /// Thread that owns the lock that this thread is waiting for.
  564. Thread* lock_owner{};
  565. /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
  566. Handle global_handle = 0;
  567. KScheduler* scheduler = nullptr;
  568. std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{};
  569. u32 ideal_core{0xFFFFFFFF};
  570. KAffinityMask affinity_mask{};
  571. s32 ideal_core_override = -1;
  572. u32 affinity_override_count = 0;
  573. u32 pausing_state = 0;
  574. bool is_running = false;
  575. bool is_cancellable = false;
  576. bool is_sync_cancelled = false;
  577. bool is_continuous_on_svc = false;
  578. bool will_be_terminated = false;
  579. bool is_phantom_mode = false;
  580. bool has_exited = false;
  581. bool was_running = false;
  582. bool signaled{};
  583. ConditionVariableThreadTree* condvar_tree{};
  584. uintptr_t condvar_key{};
  585. VAddr address_key{};
  586. u32 address_key_value{};
  587. s32 num_kernel_waiters{};
  588. using WaiterList = boost::intrusive::list<Thread>;
  589. WaiterList waiter_list{};
  590. WaiterList pinned_waiter_list{};
  591. std::string name;
  592. };
  593. } // namespace Kernel