summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.h
diff options
context:
space:
mode:
authorGravatar bunnei2020-12-21 22:36:53 -0800
committerGravatar bunnei2021-01-11 14:23:16 -0800
commit35c3c078e3c079c0a9192b411e20c71b122ff057 (patch)
tree572c0b6a47a249a78d658122de32908262ec6a69 /src/core/hle/kernel/thread.h
parentcore: hle: kernel: Begin moving common SVC results to its own header. (diff)
downloadyuzu-35c3c078e3c079c0a9192b411e20c71b122ff057.tar.gz
yuzu-35c3c078e3c079c0a9192b411e20c71b122ff057.tar.xz
yuzu-35c3c078e3c079c0a9192b411e20c71b122ff057.zip
core: hle: kernel: Update KSynchronizationObject.
Diffstat (limited to 'src/core/hle/kernel/thread.h')
-rw-r--r--src/core/hle/kernel/thread.h131
1 files changed, 46 insertions, 85 deletions
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 11ef29888..69458548b 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -14,8 +14,8 @@
14#include "common/spin_lock.h" 14#include "common/spin_lock.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/hle/kernel/k_affinity_mask.h" 16#include "core/hle/kernel/k_affinity_mask.h"
17#include "core/hle/kernel/k_synchronization_object.h"
17#include "core/hle/kernel/object.h" 18#include "core/hle/kernel/object.h"
18#include "core/hle/kernel/synchronization_object.h"
19#include "core/hle/result.h" 19#include "core/hle/result.h"
20 20
21namespace Common { 21namespace Common {
@@ -117,7 +117,7 @@ enum class ThreadSchedMasks : u32 {
117 ForcePauseMask = 0x0070, 117 ForcePauseMask = 0x0070,
118}; 118};
119 119
120class Thread final : public SynchronizationObject { 120class Thread final : public KSynchronizationObject {
121public: 121public:
122 explicit Thread(KernelCore& kernel); 122 explicit Thread(KernelCore& kernel);
123 ~Thread() override; 123 ~Thread() override;
@@ -127,10 +127,6 @@ public:
127 using ThreadContext32 = Core::ARM_Interface::ThreadContext32; 127 using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
128 using ThreadContext64 = Core::ARM_Interface::ThreadContext64; 128 using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
129 129
130 using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;
131
132 using HLECallback = std::function<bool(std::shared_ptr<Thread> thread)>;
133
134 /** 130 /**
135 * Creates and returns a new thread. The new thread is immediately scheduled 131 * Creates and returns a new thread. The new thread is immediately scheduled
136 * @param system The instance of the whole system 132 * @param system The instance of the whole system
@@ -186,10 +182,6 @@ public:
186 return HANDLE_TYPE; 182 return HANDLE_TYPE;
187 } 183 }
188 184
189 bool ShouldWait(const Thread* thread) const override;
190 void Acquire(Thread* thread) override;
191 bool IsSignaled() const override;
192
193 /** 185 /**
194 * Gets the thread's current priority 186 * Gets the thread's current priority
195 * @return The current thread's priority 187 * @return The current thread's priority
@@ -233,12 +225,14 @@ public:
233 } 225 }
234 226
235 /// Resumes a thread from waiting 227 /// Resumes a thread from waiting
236 void ResumeFromWait(); 228 void Wakeup();
237 229
238 void OnWakeUp(); 230 void OnWakeUp();
239 231
240 ResultCode Start(); 232 ResultCode Start();
241 233
234 virtual bool IsSignaled() const override;
235
242 /// Cancels a waiting operation that this thread may or may not be within. 236 /// Cancels a waiting operation that this thread may or may not be within.
243 /// 237 ///
244 /// When the thread is within a waiting state, this will set the thread's 238 /// When the thread is within a waiting state, this will set the thread's
@@ -247,29 +241,20 @@ public:
247 /// 241 ///
248 void CancelWait(); 242 void CancelWait();
249 243
250 void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); 244 void SetSynchronizationResults(KSynchronizationObject* object, ResultCode result);
251 245
252 SynchronizationObject* GetSignalingObject() const { 246 void SetSyncedObject(KSynchronizationObject* object, ResultCode result) {
253 return signaling_object; 247 SetSynchronizationResults(object, result);
254 } 248 }
255 249
256 ResultCode GetSignalingResult() const { 250 ResultCode GetWaitResult(KSynchronizationObject** out) const {
251 *out = this->signaling_object;
257 return signaling_result; 252 return signaling_result;
258 } 253 }
259 254
260 /** 255 ResultCode GetSignalingResult() const {
261 * Retrieves the index that this particular object occupies in the list of objects 256 return signaling_result;
262 * that the thread passed to WaitSynchronization, starting the search from the last element. 257 }
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 258
274 /** 259 /**
275 * Stops a thread, invalidating it from further use 260 * Stops a thread, invalidating it from further use
@@ -345,7 +330,7 @@ public:
345 return status; 330 return status;
346 } 331 }
347 332
348 void SetStatus(ThreadStatus new_status); 333 void SetState(ThreadStatus new_status);
349 334
350 s64 GetLastScheduledTick() const { 335 s64 GetLastScheduledTick() const {
351 return this->last_scheduled_tick; 336 return this->last_scheduled_tick;
@@ -387,24 +372,6 @@ public:
387 return owner_process; 372 return owner_process;
388 } 373 }
389 374
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 { 375 const MutexWaitingThreads& GetMutexWaitingThreads() const {
409 return wait_mutex_threads; 376 return wait_mutex_threads;
410 } 377 }
@@ -449,34 +416,14 @@ public:
449 arb_wait_address = address; 416 arb_wait_address = address;
450 } 417 }
451 418
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) { 419 void SetHLETimeEvent(Handle time_event) {
461 hle_time_event = time_event; 420 hle_time_event = time_event;
462 } 421 }
463 422
464 void SetHLESyncObject(SynchronizationObject* object) {
465 hle_object = object;
466 }
467
468 Handle GetHLETimeEvent() const { 423 Handle GetHLETimeEvent() const {
469 return hle_time_event; 424 return hle_time_event;
470 } 425 }
471 426
472 SynchronizationObject* GetHLESyncObject() const {
473 return hle_object;
474 }
475
476 void InvalidateHLECallback() {
477 SetHLECallback(nullptr);
478 }
479
480 bool InvokeHLECallback(std::shared_ptr<Thread> thread); 427 bool InvokeHLECallback(std::shared_ptr<Thread> thread);
481 428
482 u32 GetIdealCore() const { 429 u32 GetIdealCore() const {
@@ -500,7 +447,7 @@ public:
500 this->schedule_count = count; 447 this->schedule_count = count;
501 } 448 }
502 449
503 ThreadSchedStatus GetSchedulingStatus() const { 450 ThreadSchedStatus GetState() const {
504 return static_cast<ThreadSchedStatus>(scheduling_state & 451 return static_cast<ThreadSchedStatus>(scheduling_state &
505 static_cast<u32>(ThreadSchedMasks::LowMask)); 452 static_cast<u32>(ThreadSchedMasks::LowMask));
506 } 453 }
@@ -517,12 +464,12 @@ public:
517 is_running = value; 464 is_running = value;
518 } 465 }
519 466
520 bool IsSyncCancelled() const { 467 bool IsWaitCancelled() const {
521 return is_sync_cancelled; 468 return is_sync_cancelled;
522 } 469 }
523 470
524 void SetSyncCancelled(bool value) { 471 void ClearWaitCancelled() {
525 is_sync_cancelled = value; 472 is_sync_cancelled = false;
526 } 473 }
527 474
528 Handle GetGlobalHandle() const { 475 Handle GetGlobalHandle() const {
@@ -537,16 +484,20 @@ public:
537 waiting_for_arbitration = set; 484 waiting_for_arbitration = set;
538 } 485 }
539 486
540 bool IsWaitingSync() const { 487 bool IsCancellable() const {
541 return is_waiting_on_sync; 488 return is_cancellable;
542 } 489 }
543 490
544 void SetWaitingSync(bool is_waiting) { 491 void SetCancellable() {
545 is_waiting_on_sync = is_waiting; 492 is_cancellable = true;
546 } 493 }
547 494
548 bool IsPendingTermination() const { 495 void ClearCancellable() {
549 return will_be_terminated || GetSchedulingStatus() == ThreadSchedStatus::Exited; 496 is_cancellable = false;
497 }
498
499 bool IsTerminationRequested() const {
500 return will_be_terminated || GetState() == ThreadSchedStatus::Exited;
550 } 501 }
551 502
552 bool IsPaused() const { 503 bool IsPaused() const {
@@ -622,6 +573,18 @@ public:
622 disable_count--; 573 disable_count--;
623 } 574 }
624 575
576 void SetWaitObjectsForDebugging(KSynchronizationObject** objects, s32 num_objects) {
577 wait_objects_for_debugging.clear();
578 wait_objects_for_debugging.reserve(num_objects);
579 for (auto i = 0; i < num_objects; ++i) {
580 wait_objects_for_debugging.emplace_back(objects[i]);
581 }
582 }
583
584 const std::vector<KSynchronizationObject*>& GetWaitObjectsForDebugging() const {
585 return wait_objects_for_debugging;
586 }
587
625private: 588private:
626 friend class GlobalSchedulerContext; 589 friend class GlobalSchedulerContext;
627 friend class KScheduler; 590 friend class KScheduler;
@@ -630,7 +593,6 @@ private:
630 void SetSchedulingStatus(ThreadSchedStatus new_status); 593 void SetSchedulingStatus(ThreadSchedStatus new_status);
631 void AddSchedulingFlag(ThreadSchedFlags flag); 594 void AddSchedulingFlag(ThreadSchedFlags flag);
632 void RemoveSchedulingFlag(ThreadSchedFlags flag); 595 void RemoveSchedulingFlag(ThreadSchedFlags flag);
633
634 void SetCurrentPriority(u32 new_priority); 596 void SetCurrentPriority(u32 new_priority);
635 597
636 Common::SpinLock context_guard{}; 598 Common::SpinLock context_guard{};
@@ -671,10 +633,10 @@ private:
671 Process* owner_process; 633 Process* owner_process;
672 634
673 /// Objects that the thread is waiting on, in the same order as they were 635 /// Objects that the thread is waiting on, in the same order as they were
674 /// passed to WaitSynchronization. 636 /// passed to WaitSynchronization. This is used for debugging only.
675 ThreadSynchronizationObjects* wait_objects; 637 std::vector<KSynchronizationObject*> wait_objects_for_debugging;
676 638
677 SynchronizationObject* signaling_object; 639 KSynchronizationObject* signaling_object;
678 ResultCode signaling_result{RESULT_SUCCESS}; 640 ResultCode signaling_result{RESULT_SUCCESS};
679 641
680 /// List of threads that are waiting for a mutex that is held by this thread. 642 /// List of threads that are waiting for a mutex that is held by this thread.
@@ -697,10 +659,7 @@ private:
697 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. 659 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
698 Handle global_handle = 0; 660 Handle global_handle = 0;
699 661
700 /// Callback for HLE Events
701 HLECallback hle_callback;
702 Handle hle_time_event; 662 Handle hle_time_event;
703 SynchronizationObject* hle_object;
704 663
705 KScheduler* scheduler = nullptr; 664 KScheduler* scheduler = nullptr;
706 665
@@ -714,7 +673,7 @@ private:
714 673
715 u32 pausing_state = 0; 674 u32 pausing_state = 0;
716 bool is_running = false; 675 bool is_running = false;
717 bool is_waiting_on_sync = false; 676 bool is_cancellable = false;
718 bool is_sync_cancelled = false; 677 bool is_sync_cancelled = false;
719 678
720 bool is_continuous_on_svc = false; 679 bool is_continuous_on_svc = false;
@@ -725,6 +684,8 @@ private:
725 684
726 bool was_running = false; 685 bool was_running = false;
727 686
687 bool signaled{};
688
728 std::string name; 689 std::string name;
729}; 690};
730 691