diff options
| author | 2020-12-21 22:36:53 -0800 | |
|---|---|---|
| committer | 2021-01-11 14:23:16 -0800 | |
| commit | 35c3c078e3c079c0a9192b411e20c71b122ff057 (patch) | |
| tree | 572c0b6a47a249a78d658122de32908262ec6a69 /src/core/hle/kernel/thread.h | |
| parent | core: hle: kernel: Begin moving common SVC results to its own header. (diff) | |
| download | yuzu-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.h | 131 |
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 | ||
| 21 | namespace Common { | 21 | namespace Common { |
| @@ -117,7 +117,7 @@ enum class ThreadSchedMasks : u32 { | |||
| 117 | ForcePauseMask = 0x0070, | 117 | ForcePauseMask = 0x0070, |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | class Thread final : public SynchronizationObject { | 120 | class Thread final : public KSynchronizationObject { |
| 121 | public: | 121 | public: |
| 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 | |||
| 625 | private: | 588 | private: |
| 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 | ||