summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/thread.h')
-rw-r--r--src/core/hle/kernel/thread.h497
1 files changed, 274 insertions, 223 deletions
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 11ef29888..6b66c9a0e 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -6,16 +6,21 @@
6 6
7#include <array> 7#include <array>
8#include <functional> 8#include <functional>
9#include <span>
9#include <string> 10#include <string>
10#include <utility> 11#include <utility>
11#include <vector> 12#include <vector>
12 13
14#include <boost/intrusive/list.hpp>
15
13#include "common/common_types.h" 16#include "common/common_types.h"
17#include "common/intrusive_red_black_tree.h"
14#include "common/spin_lock.h" 18#include "common/spin_lock.h"
15#include "core/arm/arm_interface.h" 19#include "core/arm/arm_interface.h"
16#include "core/hle/kernel/k_affinity_mask.h" 20#include "core/hle/kernel/k_affinity_mask.h"
21#include "core/hle/kernel/k_synchronization_object.h"
17#include "core/hle/kernel/object.h" 22#include "core/hle/kernel/object.h"
18#include "core/hle/kernel/synchronization_object.h" 23#include "core/hle/kernel/svc_common.h"
19#include "core/hle/result.h" 24#include "core/hle/result.h"
20 25
21namespace Common { 26namespace Common {
@@ -73,19 +78,24 @@ enum ThreadProcessorId : s32 {
73 (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3) 78 (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3)
74}; 79};
75 80
76enum class ThreadStatus { 81enum class ThreadState : u16 {
77 Ready, ///< Ready to run 82 Initialized = 0,
78 Paused, ///< Paused by SetThreadActivity or debug 83 Waiting = 1,
79 WaitHLEEvent, ///< Waiting for hle event to finish 84 Runnable = 2,
80 WaitSleep, ///< Waiting due to a SleepThread SVC 85 Terminated = 3,
81 WaitIPC, ///< Waiting for the reply from an IPC request 86
82 WaitSynch, ///< Waiting due to WaitSynchronization 87 SuspendShift = 4,
83 WaitMutex, ///< Waiting due to an ArbitrateLock svc 88 Mask = (1 << SuspendShift) - 1,
84 WaitCondVar, ///< Waiting due to an WaitProcessWideKey svc 89
85 WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc 90 ProcessSuspended = (1 << (0 + SuspendShift)),
86 Dormant, ///< Created but not yet made ready 91 ThreadSuspended = (1 << (1 + SuspendShift)),
87 Dead ///< Run to completion, or forcefully terminated 92 DebugSuspended = (1 << (2 + SuspendShift)),
93 BacktraceSuspended = (1 << (3 + SuspendShift)),
94 InitSuspended = (1 << (4 + SuspendShift)),
95
96 SuspendFlagMask = ((1 << 5) - 1) << SuspendShift,
88}; 97};
98DECLARE_ENUM_FLAG_OPERATORS(ThreadState);
89 99
90enum class ThreadWakeupReason { 100enum class ThreadWakeupReason {
91 Signal, // The thread was woken up by WakeupAllWaitingThreads due to an object signal. 101 Signal, // The thread was woken up by WakeupAllWaitingThreads due to an object signal.
@@ -97,13 +107,6 @@ enum class ThreadActivity : u32 {
97 Paused = 1, 107 Paused = 1,
98}; 108};
99 109
100enum class ThreadSchedStatus : u32 {
101 None = 0,
102 Paused = 1,
103 Runnable = 2,
104 Exited = 3,
105};
106
107enum class ThreadSchedFlags : u32 { 110enum class ThreadSchedFlags : u32 {
108 ProcessPauseFlag = 1 << 4, 111 ProcessPauseFlag = 1 << 4,
109 ThreadPauseFlag = 1 << 5, 112 ThreadPauseFlag = 1 << 5,
@@ -111,13 +114,20 @@ enum class ThreadSchedFlags : u32 {
111 KernelInitPauseFlag = 1 << 8, 114 KernelInitPauseFlag = 1 << 8,
112}; 115};
113 116
114enum class ThreadSchedMasks : u32 { 117enum class ThreadWaitReasonForDebugging : u32 {
115 LowMask = 0x000f, 118 None, ///< Thread is not waiting
116 HighMask = 0xfff0, 119 Sleep, ///< Thread is waiting due to a SleepThread SVC
117 ForcePauseMask = 0x0070, 120 IPC, ///< Thread is waiting for the reply from an IPC request
121 Synchronization, ///< Thread is waiting due to a WaitSynchronization SVC
122 ConditionVar, ///< Thread is waiting due to a WaitProcessWideKey SVC
123 Arbitration, ///< Thread is waiting due to a SignalToAddress/WaitForAddress SVC
124 Suspended, ///< Thread is waiting due to process suspension
118}; 125};
119 126
120class Thread final : public SynchronizationObject { 127class Thread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> {
128 friend class KScheduler;
129 friend class Process;
130
121public: 131public:
122 explicit Thread(KernelCore& kernel); 132 explicit Thread(KernelCore& kernel);
123 ~Thread() override; 133 ~Thread() override;
@@ -127,10 +137,6 @@ public:
127 using ThreadContext32 = Core::ARM_Interface::ThreadContext32; 137 using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
128 using ThreadContext64 = Core::ARM_Interface::ThreadContext64; 138 using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
129 139
130 using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;
131
132 using HLECallback = std::function<bool(std::shared_ptr<Thread> thread)>;
133
134 /** 140 /**
135 * Creates and returns a new thread. The new thread is immediately scheduled 141 * Creates and returns a new thread. The new thread is immediately scheduled
136 * @param system The instance of the whole system 142 * @param system The instance of the whole system
@@ -186,59 +192,54 @@ public:
186 return HANDLE_TYPE; 192 return HANDLE_TYPE;
187 } 193 }
188 194
189 bool ShouldWait(const Thread* thread) const override;
190 void Acquire(Thread* thread) override;
191 bool IsSignaled() const override;
192
193 /** 195 /**
194 * Gets the thread's current priority 196 * Gets the thread's current priority
195 * @return The current thread's priority 197 * @return The current thread's priority
196 */ 198 */
197 u32 GetPriority() const { 199 [[nodiscard]] s32 GetPriority() const {
198 return current_priority; 200 return current_priority;
199 } 201 }
200 202
201 /** 203 /**
204 * Sets the thread's current priority.
205 * @param priority The new priority.
206 */
207 void SetPriority(s32 priority) {
208 current_priority = priority;
209 }
210
211 /**
202 * Gets the thread's nominal priority. 212 * Gets the thread's nominal priority.
203 * @return The current thread's nominal priority. 213 * @return The current thread's nominal priority.
204 */ 214 */
205 u32 GetNominalPriority() const { 215 [[nodiscard]] s32 GetBasePriority() const {
206 return nominal_priority; 216 return base_priority;
207 } 217 }
208 218
209 /** 219 /**
210 * Sets the thread's current priority 220 * Sets the thread's nominal priority.
211 * @param priority The new priority 221 * @param priority The new priority.
212 */ 222 */
213 void SetPriority(u32 priority); 223 void SetBasePriority(u32 priority);
214
215 /// Adds a thread to the list of threads that are waiting for a lock held by this thread.
216 void AddMutexWaiter(std::shared_ptr<Thread> thread);
217
218 /// Removes a thread from the list of threads that are waiting for a lock held by this thread.
219 void RemoveMutexWaiter(std::shared_ptr<Thread> thread);
220
221 /// Recalculates the current priority taking into account priority inheritance.
222 void UpdatePriority();
223 224
224 /// Changes the core that the thread is running or scheduled to run on. 225 /// Changes the core that the thread is running or scheduled to run on.
225 ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask); 226 [[nodiscard]] ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
226 227
227 /** 228 /**
228 * Gets the thread's thread ID 229 * Gets the thread's thread ID
229 * @return The thread's ID 230 * @return The thread's ID
230 */ 231 */
231 u64 GetThreadID() const { 232 [[nodiscard]] u64 GetThreadID() const {
232 return thread_id; 233 return thread_id;
233 } 234 }
234 235
235 /// Resumes a thread from waiting 236 /// Resumes a thread from waiting
236 void ResumeFromWait(); 237 void Wakeup();
237
238 void OnWakeUp();
239 238
240 ResultCode Start(); 239 ResultCode Start();
241 240
241 virtual bool IsSignaled() const override;
242
242 /// Cancels a waiting operation that this thread may or may not be within. 243 /// Cancels a waiting operation that this thread may or may not be within.
243 /// 244 ///
244 /// When the thread is within a waiting state, this will set the thread's 245 /// When the thread is within a waiting state, this will set the thread's
@@ -247,29 +248,20 @@ public:
247 /// 248 ///
248 void CancelWait(); 249 void CancelWait();
249 250
250 void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); 251 void SetSynchronizationResults(KSynchronizationObject* object, ResultCode result);
251 252
252 SynchronizationObject* GetSignalingObject() const { 253 void SetSyncedObject(KSynchronizationObject* object, ResultCode result) {
253 return signaling_object; 254 SetSynchronizationResults(object, result);
254 } 255 }
255 256
256 ResultCode GetSignalingResult() const { 257 ResultCode GetWaitResult(KSynchronizationObject** out) const {
258 *out = signaling_object;
257 return signaling_result; 259 return signaling_result;
258 } 260 }
259 261
260 /** 262 ResultCode GetSignalingResult() const {
261 * Retrieves the index that this particular object occupies in the list of objects 263 return signaling_result;
262 * that the thread passed to WaitSynchronization, starting the search from the last element. 264 }
263 *
264 * It is used to set the output index of WaitSynchronization when the thread is awakened.
265 *
266 * When a thread wakes up due to an object signal, the kernel will use the index of the last
267 * matching object in the wait objects list in case of having multiple instances of the same
268 * object in the list.
269 *
270 * @param object Object to query the index of.
271 */
272 s32 GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const;
273 265
274 /** 266 /**
275 * Stops a thread, invalidating it from further use 267 * Stops a thread, invalidating it from further use
@@ -341,18 +333,22 @@ public:
341 333
342 std::shared_ptr<Common::Fiber>& GetHostContext(); 334 std::shared_ptr<Common::Fiber>& GetHostContext();
343 335
344 ThreadStatus GetStatus() const { 336 ThreadState GetState() const {
345 return status; 337 return thread_state & ThreadState::Mask;
338 }
339
340 ThreadState GetRawState() const {
341 return thread_state;
346 } 342 }
347 343
348 void SetStatus(ThreadStatus new_status); 344 void SetState(ThreadState state);
349 345
350 s64 GetLastScheduledTick() const { 346 s64 GetLastScheduledTick() const {
351 return this->last_scheduled_tick; 347 return last_scheduled_tick;
352 } 348 }
353 349
354 void SetLastScheduledTick(s64 tick) { 350 void SetLastScheduledTick(s64 tick) {
355 this->last_scheduled_tick = tick; 351 last_scheduled_tick = tick;
356 } 352 }
357 353
358 u64 GetTotalCPUTimeTicks() const { 354 u64 GetTotalCPUTimeTicks() const {
@@ -387,98 +383,18 @@ public:
387 return owner_process; 383 return owner_process;
388 } 384 }
389 385
390 const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
391 return *wait_objects;
392 }
393
394 void SetSynchronizationObjects(ThreadSynchronizationObjects* objects) {
395 wait_objects = objects;
396 }
397
398 void ClearSynchronizationObjects() {
399 for (const auto& waiting_object : *wait_objects) {
400 waiting_object->RemoveWaitingThread(SharedFrom(this));
401 }
402 wait_objects->clear();
403 }
404
405 /// Determines whether all the objects this thread is waiting on are ready.
406 bool AllSynchronizationObjectsReady() const;
407
408 const MutexWaitingThreads& GetMutexWaitingThreads() const { 386 const MutexWaitingThreads& GetMutexWaitingThreads() const {
409 return wait_mutex_threads; 387 return wait_mutex_threads;
410 } 388 }
411 389
412 Thread* GetLockOwner() const { 390 Thread* GetLockOwner() const {
413 return lock_owner.get(); 391 return lock_owner;
414 }
415
416 void SetLockOwner(std::shared_ptr<Thread> owner) {
417 lock_owner = std::move(owner);
418 }
419
420 VAddr GetCondVarWaitAddress() const {
421 return condvar_wait_address;
422 }
423
424 void SetCondVarWaitAddress(VAddr address) {
425 condvar_wait_address = address;
426 }
427
428 VAddr GetMutexWaitAddress() const {
429 return mutex_wait_address;
430 }
431
432 void SetMutexWaitAddress(VAddr address) {
433 mutex_wait_address = address;
434 }
435
436 Handle GetWaitHandle() const {
437 return wait_handle;
438 }
439
440 void SetWaitHandle(Handle handle) {
441 wait_handle = handle;
442 }
443
444 VAddr GetArbiterWaitAddress() const {
445 return arb_wait_address;
446 }
447
448 void SetArbiterWaitAddress(VAddr address) {
449 arb_wait_address = address;
450 }
451
452 bool HasHLECallback() const {
453 return hle_callback != nullptr;
454 }
455
456 void SetHLECallback(HLECallback callback) {
457 hle_callback = std::move(callback);
458 }
459
460 void SetHLETimeEvent(Handle time_event) {
461 hle_time_event = time_event;
462 }
463
464 void SetHLESyncObject(SynchronizationObject* object) {
465 hle_object = object;
466 }
467
468 Handle GetHLETimeEvent() const {
469 return hle_time_event;
470 }
471
472 SynchronizationObject* GetHLESyncObject() const {
473 return hle_object;
474 } 392 }
475 393
476 void InvalidateHLECallback() { 394 void SetLockOwner(Thread* owner) {
477 SetHLECallback(nullptr); 395 lock_owner = owner;
478 } 396 }
479 397
480 bool InvokeHLECallback(std::shared_ptr<Thread> thread);
481
482 u32 GetIdealCore() const { 398 u32 GetIdealCore() const {
483 return ideal_core; 399 return ideal_core;
484 } 400 }
@@ -493,20 +409,11 @@ public:
493 ResultCode Sleep(s64 nanoseconds); 409 ResultCode Sleep(s64 nanoseconds);
494 410
495 s64 GetYieldScheduleCount() const { 411 s64 GetYieldScheduleCount() const {
496 return this->schedule_count; 412 return schedule_count;
497 } 413 }
498 414
499 void SetYieldScheduleCount(s64 count) { 415 void SetYieldScheduleCount(s64 count) {
500 this->schedule_count = count; 416 schedule_count = count;
501 }
502
503 ThreadSchedStatus GetSchedulingStatus() const {
504 return static_cast<ThreadSchedStatus>(scheduling_state &
505 static_cast<u32>(ThreadSchedMasks::LowMask));
506 }
507
508 bool IsRunnable() const {
509 return scheduling_state == static_cast<u32>(ThreadSchedStatus::Runnable);
510 } 417 }
511 418
512 bool IsRunning() const { 419 bool IsRunning() const {
@@ -517,36 +424,32 @@ public:
517 is_running = value; 424 is_running = value;
518 } 425 }
519 426
520 bool IsSyncCancelled() const { 427 bool IsWaitCancelled() const {
521 return is_sync_cancelled; 428 return is_sync_cancelled;
522 } 429 }
523 430
524 void SetSyncCancelled(bool value) { 431 void ClearWaitCancelled() {
525 is_sync_cancelled = value; 432 is_sync_cancelled = false;
526 } 433 }
527 434
528 Handle GetGlobalHandle() const { 435 Handle GetGlobalHandle() const {
529 return global_handle; 436 return global_handle;
530 } 437 }
531 438
532 bool IsWaitingForArbitration() const { 439 bool IsCancellable() const {
533 return waiting_for_arbitration; 440 return is_cancellable;
534 } 441 }
535 442
536 void WaitForArbitration(bool set) { 443 void SetCancellable() {
537 waiting_for_arbitration = set; 444 is_cancellable = true;
538 } 445 }
539 446
540 bool IsWaitingSync() const { 447 void ClearCancellable() {
541 return is_waiting_on_sync; 448 is_cancellable = false;
542 } 449 }
543 450
544 void SetWaitingSync(bool is_waiting) { 451 bool IsTerminationRequested() const {
545 is_waiting_on_sync = is_waiting; 452 return will_be_terminated || GetRawState() == ThreadState::Terminated;
546 }
547
548 bool IsPendingTermination() const {
549 return will_be_terminated || GetSchedulingStatus() == ThreadSchedStatus::Exited;
550 } 453 }
551 454
552 bool IsPaused() const { 455 bool IsPaused() const {
@@ -578,21 +481,21 @@ public:
578 constexpr QueueEntry() = default; 481 constexpr QueueEntry() = default;
579 482
580 constexpr void Initialize() { 483 constexpr void Initialize() {
581 this->prev = nullptr; 484 prev = nullptr;
582 this->next = nullptr; 485 next = nullptr;
583 } 486 }
584 487
585 constexpr Thread* GetPrev() const { 488 constexpr Thread* GetPrev() const {
586 return this->prev; 489 return prev;
587 } 490 }
588 constexpr Thread* GetNext() const { 491 constexpr Thread* GetNext() const {
589 return this->next; 492 return next;
590 } 493 }
591 constexpr void SetPrev(Thread* thread) { 494 constexpr void SetPrev(Thread* thread) {
592 this->prev = thread; 495 prev = thread;
593 } 496 }
594 constexpr void SetNext(Thread* thread) { 497 constexpr void SetNext(Thread* thread) {
595 this->next = thread; 498 next = thread;
596 } 499 }
597 500
598 private: 501 private:
@@ -601,11 +504,11 @@ public:
601 }; 504 };
602 505
603 QueueEntry& GetPriorityQueueEntry(s32 core) { 506 QueueEntry& GetPriorityQueueEntry(s32 core) {
604 return this->per_core_priority_queue_entry[core]; 507 return per_core_priority_queue_entry[core];
605 } 508 }
606 509
607 const QueueEntry& GetPriorityQueueEntry(s32 core) const { 510 const QueueEntry& GetPriorityQueueEntry(s32 core) const {
608 return this->per_core_priority_queue_entry[core]; 511 return per_core_priority_queue_entry[core];
609 } 512 }
610 513
611 s32 GetDisableDispatchCount() const { 514 s32 GetDisableDispatchCount() const {
@@ -622,24 +525,170 @@ public:
622 disable_count--; 525 disable_count--;
623 } 526 }
624 527
528 void SetWaitReasonForDebugging(ThreadWaitReasonForDebugging reason) {
529 wait_reason_for_debugging = reason;
530 }
531
532 [[nodiscard]] ThreadWaitReasonForDebugging GetWaitReasonForDebugging() const {
533 return wait_reason_for_debugging;
534 }
535
536 void SetWaitObjectsForDebugging(const std::span<KSynchronizationObject*>& objects) {
537 wait_objects_for_debugging.clear();
538 wait_objects_for_debugging.reserve(objects.size());
539 for (const auto& object : objects) {
540 wait_objects_for_debugging.emplace_back(object);
541 }
542 }
543
544 [[nodiscard]] const std::vector<KSynchronizationObject*>& GetWaitObjectsForDebugging() const {
545 return wait_objects_for_debugging;
546 }
547
548 void SetMutexWaitAddressForDebugging(VAddr address) {
549 mutex_wait_address_for_debugging = address;
550 }
551
552 [[nodiscard]] VAddr GetMutexWaitAddressForDebugging() const {
553 return mutex_wait_address_for_debugging;
554 }
555
556 void AddWaiter(Thread* thread);
557
558 void RemoveWaiter(Thread* thread);
559
560 [[nodiscard]] Thread* RemoveWaiterByKey(s32* out_num_waiters, VAddr key);
561
562 [[nodiscard]] VAddr GetAddressKey() const {
563 return address_key;
564 }
565
566 [[nodiscard]] u32 GetAddressKeyValue() const {
567 return address_key_value;
568 }
569
570 void SetAddressKey(VAddr key) {
571 address_key = key;
572 }
573
574 void SetAddressKey(VAddr key, u32 val) {
575 address_key = key;
576 address_key_value = val;
577 }
578
625private: 579private:
626 friend class GlobalSchedulerContext; 580 static constexpr size_t PriorityInheritanceCountMax = 10;
627 friend class KScheduler; 581 union SyncObjectBuffer {
628 friend class Process; 582 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
583 std::array<Handle,
584 Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))>
585 handles;
586 constexpr SyncObjectBuffer() {}
587 };
588 static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles));
589
590 struct ConditionVariableComparator {
591 struct LightCompareType {
592 u64 cv_key{};
593 s32 priority{};
594
595 [[nodiscard]] constexpr u64 GetConditionVariableKey() const {
596 return cv_key;
597 }
598
599 [[nodiscard]] constexpr s32 GetPriority() const {
600 return priority;
601 }
602 };
603
604 template <typename T>
605 requires(
606 std::same_as<T, Thread> ||
607 std::same_as<T, LightCompareType>) static constexpr int Compare(const T& lhs,
608 const Thread& rhs) {
609 const uintptr_t l_key = lhs.GetConditionVariableKey();
610 const uintptr_t r_key = rhs.GetConditionVariableKey();
611
612 if (l_key < r_key) {
613 // Sort first by key
614 return -1;
615 } else if (l_key == r_key && lhs.GetPriority() < rhs.GetPriority()) {
616 // And then by priority.
617 return -1;
618 } else {
619 return 1;
620 }
621 }
622 };
623
624 Common::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node{};
625
626 using ConditionVariableThreadTreeTraits =
627 Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&Thread::condvar_arbiter_tree_node>;
628 using ConditionVariableThreadTree =
629 ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
630
631public:
632 using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
633
634 [[nodiscard]] uintptr_t GetConditionVariableKey() const {
635 return condvar_key;
636 }
637
638 [[nodiscard]] uintptr_t GetAddressArbiterKey() const {
639 return condvar_key;
640 }
629 641
630 void SetSchedulingStatus(ThreadSchedStatus new_status); 642 void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, uintptr_t cv_key,
643 u32 value) {
644 condvar_tree = tree;
645 condvar_key = cv_key;
646 address_key = address;
647 address_key_value = value;
648 }
649
650 void ClearConditionVariable() {
651 condvar_tree = nullptr;
652 }
653
654 [[nodiscard]] bool IsWaitingForConditionVariable() const {
655 return condvar_tree != nullptr;
656 }
657
658 void SetAddressArbiter(ConditionVariableThreadTree* tree, uintptr_t address) {
659 condvar_tree = tree;
660 condvar_key = address;
661 }
662
663 void ClearAddressArbiter() {
664 condvar_tree = nullptr;
665 }
666
667 [[nodiscard]] bool IsWaitingForAddressArbiter() const {
668 return condvar_tree != nullptr;
669 }
670
671 [[nodiscard]] ConditionVariableThreadTree* GetConditionVariableTree() const {
672 return condvar_tree;
673 }
674
675 [[nodiscard]] bool HasWaiters() const {
676 return !waiter_list.empty();
677 }
678
679private:
631 void AddSchedulingFlag(ThreadSchedFlags flag); 680 void AddSchedulingFlag(ThreadSchedFlags flag);
632 void RemoveSchedulingFlag(ThreadSchedFlags flag); 681 void RemoveSchedulingFlag(ThreadSchedFlags flag);
633 682 void AddWaiterImpl(Thread* thread);
634 void SetCurrentPriority(u32 new_priority); 683 void RemoveWaiterImpl(Thread* thread);
684 static void RestorePriority(KernelCore& kernel, Thread* thread);
635 685
636 Common::SpinLock context_guard{}; 686 Common::SpinLock context_guard{};
637 ThreadContext32 context_32{}; 687 ThreadContext32 context_32{};
638 ThreadContext64 context_64{}; 688 ThreadContext64 context_64{};
639 std::shared_ptr<Common::Fiber> host_context{}; 689 std::shared_ptr<Common::Fiber> host_context{};
640 690
641 ThreadStatus status = ThreadStatus::Dormant; 691 ThreadState thread_state = ThreadState::Initialized;
642 u32 scheduling_state = 0;
643 692
644 u64 thread_id = 0; 693 u64 thread_id = 0;
645 694
@@ -652,11 +701,11 @@ private:
652 /// Nominal thread priority, as set by the emulated application. 701 /// Nominal thread priority, as set by the emulated application.
653 /// The nominal priority is the thread priority without priority 702 /// The nominal priority is the thread priority without priority
654 /// inheritance taken into account. 703 /// inheritance taken into account.
655 u32 nominal_priority = 0; 704 s32 base_priority{};
656 705
657 /// Current thread priority. This may change over the course of the 706 /// Current thread priority. This may change over the course of the
658 /// thread's lifetime in order to facilitate priority inheritance. 707 /// thread's lifetime in order to facilitate priority inheritance.
659 u32 current_priority = 0; 708 s32 current_priority{};
660 709
661 u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. 710 u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks.
662 s64 schedule_count{}; 711 s64 schedule_count{};
@@ -671,37 +720,27 @@ private:
671 Process* owner_process; 720 Process* owner_process;
672 721
673 /// Objects that the thread is waiting on, in the same order as they were 722 /// Objects that the thread is waiting on, in the same order as they were
674 /// passed to WaitSynchronization. 723 /// passed to WaitSynchronization. This is used for debugging only.
675 ThreadSynchronizationObjects* wait_objects; 724 std::vector<KSynchronizationObject*> wait_objects_for_debugging;
676 725
677 SynchronizationObject* signaling_object; 726 /// The current mutex wait address. This is used for debugging only.
727 VAddr mutex_wait_address_for_debugging{};
728
729 /// The reason the thread is waiting. This is used for debugging only.
730 ThreadWaitReasonForDebugging wait_reason_for_debugging{};
731
732 KSynchronizationObject* signaling_object;
678 ResultCode signaling_result{RESULT_SUCCESS}; 733 ResultCode signaling_result{RESULT_SUCCESS};
679 734
680 /// List of threads that are waiting for a mutex that is held by this thread. 735 /// List of threads that are waiting for a mutex that is held by this thread.
681 MutexWaitingThreads wait_mutex_threads; 736 MutexWaitingThreads wait_mutex_threads;
682 737
683 /// Thread that owns the lock that this thread is waiting for. 738 /// Thread that owns the lock that this thread is waiting for.
684 std::shared_ptr<Thread> lock_owner; 739 Thread* lock_owner{};
685
686 /// If waiting on a ConditionVariable, this is the ConditionVariable address
687 VAddr condvar_wait_address = 0;
688 /// If waiting on a Mutex, this is the mutex address
689 VAddr mutex_wait_address = 0;
690 /// The handle used to wait for the mutex.
691 Handle wait_handle = 0;
692
693 /// If waiting for an AddressArbiter, this is the address being waited on.
694 VAddr arb_wait_address{0};
695 bool waiting_for_arbitration{};
696 740
697 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. 741 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
698 Handle global_handle = 0; 742 Handle global_handle = 0;
699 743
700 /// Callback for HLE Events
701 HLECallback hle_callback;
702 Handle hle_time_event;
703 SynchronizationObject* hle_object;
704
705 KScheduler* scheduler = nullptr; 744 KScheduler* scheduler = nullptr;
706 745
707 std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{}; 746 std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{};
@@ -714,7 +753,7 @@ private:
714 753
715 u32 pausing_state = 0; 754 u32 pausing_state = 0;
716 bool is_running = false; 755 bool is_running = false;
717 bool is_waiting_on_sync = false; 756 bool is_cancellable = false;
718 bool is_sync_cancelled = false; 757 bool is_sync_cancelled = false;
719 758
720 bool is_continuous_on_svc = false; 759 bool is_continuous_on_svc = false;
@@ -725,6 +764,18 @@ private:
725 764
726 bool was_running = false; 765 bool was_running = false;
727 766
767 bool signaled{};
768
769 ConditionVariableThreadTree* condvar_tree{};
770 uintptr_t condvar_key{};
771 VAddr address_key{};
772 u32 address_key_value{};
773 s32 num_kernel_waiters{};
774
775 using WaiterList = boost::intrusive::list<Thread>;
776 WaiterList waiter_list{};
777 WaiterList pinned_waiter_list{};
778
728 std::string name; 779 std::string name;
729}; 780};
730 781