diff options
Diffstat (limited to 'src/core/hle/kernel/thread.h')
| -rw-r--r-- | src/core/hle/kernel/thread.h | 120 |
1 files changed, 85 insertions, 35 deletions
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 8daf79fac..11ef29888 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <functional> | 8 | #include <functional> |
| 8 | #include <string> | 9 | #include <string> |
| 9 | #include <utility> | 10 | #include <utility> |
| @@ -12,6 +13,7 @@ | |||
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | #include "common/spin_lock.h" | 14 | #include "common/spin_lock.h" |
| 14 | #include "core/arm/arm_interface.h" | 15 | #include "core/arm/arm_interface.h" |
| 16 | #include "core/hle/kernel/k_affinity_mask.h" | ||
| 15 | #include "core/hle/kernel/object.h" | 17 | #include "core/hle/kernel/object.h" |
| 16 | #include "core/hle/kernel/synchronization_object.h" | 18 | #include "core/hle/kernel/synchronization_object.h" |
| 17 | #include "core/hle/result.h" | 19 | #include "core/hle/result.h" |
| @@ -27,10 +29,10 @@ class System; | |||
| 27 | 29 | ||
| 28 | namespace Kernel { | 30 | namespace Kernel { |
| 29 | 31 | ||
| 30 | class GlobalScheduler; | 32 | class GlobalSchedulerContext; |
| 31 | class KernelCore; | 33 | class KernelCore; |
| 32 | class Process; | 34 | class Process; |
| 33 | class Scheduler; | 35 | class KScheduler; |
| 34 | 36 | ||
| 35 | enum ThreadPriority : u32 { | 37 | enum ThreadPriority : u32 { |
| 36 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority | 38 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority |
| @@ -72,7 +74,6 @@ enum ThreadProcessorId : s32 { | |||
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | enum class ThreadStatus { | 76 | enum class ThreadStatus { |
| 75 | Running, ///< Currently running | ||
| 76 | Ready, ///< Ready to run | 77 | Ready, ///< Ready to run |
| 77 | Paused, ///< Paused by SetThreadActivity or debug | 78 | Paused, ///< Paused by SetThreadActivity or debug |
| 78 | WaitHLEEvent, ///< Waiting for hle event to finish | 79 | WaitHLEEvent, ///< Waiting for hle event to finish |
| @@ -248,10 +249,6 @@ public: | |||
| 248 | 249 | ||
| 249 | void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); | 250 | void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); |
| 250 | 251 | ||
| 251 | Core::ARM_Interface& ArmInterface(); | ||
| 252 | |||
| 253 | const Core::ARM_Interface& ArmInterface() const; | ||
| 254 | |||
| 255 | SynchronizationObject* GetSignalingObject() const { | 252 | SynchronizationObject* GetSignalingObject() const { |
| 256 | return signaling_object; | 253 | return signaling_object; |
| 257 | } | 254 | } |
| @@ -350,8 +347,12 @@ public: | |||
| 350 | 347 | ||
| 351 | void SetStatus(ThreadStatus new_status); | 348 | void SetStatus(ThreadStatus new_status); |
| 352 | 349 | ||
| 353 | u64 GetLastRunningTicks() const { | 350 | s64 GetLastScheduledTick() const { |
| 354 | return last_running_ticks; | 351 | return this->last_scheduled_tick; |
| 352 | } | ||
| 353 | |||
| 354 | void SetLastScheduledTick(s64 tick) { | ||
| 355 | this->last_scheduled_tick = tick; | ||
| 355 | } | 356 | } |
| 356 | 357 | ||
| 357 | u64 GetTotalCPUTimeTicks() const { | 358 | u64 GetTotalCPUTimeTicks() const { |
| @@ -366,10 +367,18 @@ public: | |||
| 366 | return processor_id; | 367 | return processor_id; |
| 367 | } | 368 | } |
| 368 | 369 | ||
| 370 | s32 GetActiveCore() const { | ||
| 371 | return GetProcessorID(); | ||
| 372 | } | ||
| 373 | |||
| 369 | void SetProcessorID(s32 new_core) { | 374 | void SetProcessorID(s32 new_core) { |
| 370 | processor_id = new_core; | 375 | processor_id = new_core; |
| 371 | } | 376 | } |
| 372 | 377 | ||
| 378 | void SetActiveCore(s32 new_core) { | ||
| 379 | processor_id = new_core; | ||
| 380 | } | ||
| 381 | |||
| 373 | Process* GetOwnerProcess() { | 382 | Process* GetOwnerProcess() { |
| 374 | return owner_process; | 383 | return owner_process; |
| 375 | } | 384 | } |
| @@ -474,7 +483,7 @@ public: | |||
| 474 | return ideal_core; | 483 | return ideal_core; |
| 475 | } | 484 | } |
| 476 | 485 | ||
| 477 | u64 GetAffinityMask() const { | 486 | const KAffinityMask& GetAffinityMask() const { |
| 478 | return affinity_mask; | 487 | return affinity_mask; |
| 479 | } | 488 | } |
| 480 | 489 | ||
| @@ -483,21 +492,12 @@ public: | |||
| 483 | /// Sleeps this thread for the given amount of nanoseconds. | 492 | /// Sleeps this thread for the given amount of nanoseconds. |
| 484 | ResultCode Sleep(s64 nanoseconds); | 493 | ResultCode Sleep(s64 nanoseconds); |
| 485 | 494 | ||
| 486 | /// Yields this thread without rebalancing loads. | 495 | s64 GetYieldScheduleCount() const { |
| 487 | std::pair<ResultCode, bool> YieldSimple(); | 496 | return this->schedule_count; |
| 488 | |||
| 489 | /// Yields this thread and does a load rebalancing. | ||
| 490 | std::pair<ResultCode, bool> YieldAndBalanceLoad(); | ||
| 491 | |||
| 492 | /// Yields this thread and if the core is left idle, loads are rebalanced | ||
| 493 | std::pair<ResultCode, bool> YieldAndWaitForLoadBalancing(); | ||
| 494 | |||
| 495 | void IncrementYieldCount() { | ||
| 496 | yield_count++; | ||
| 497 | } | 497 | } |
| 498 | 498 | ||
| 499 | u64 GetYieldCount() const { | 499 | void SetYieldScheduleCount(s64 count) { |
| 500 | return yield_count; | 500 | this->schedule_count = count; |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | ThreadSchedStatus GetSchedulingStatus() const { | 503 | ThreadSchedStatus GetSchedulingStatus() const { |
| @@ -573,9 +573,59 @@ public: | |||
| 573 | return has_exited; | 573 | return has_exited; |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | class QueueEntry { | ||
| 577 | public: | ||
| 578 | constexpr QueueEntry() = default; | ||
| 579 | |||
| 580 | constexpr void Initialize() { | ||
| 581 | this->prev = nullptr; | ||
| 582 | this->next = nullptr; | ||
| 583 | } | ||
| 584 | |||
| 585 | constexpr Thread* GetPrev() const { | ||
| 586 | return this->prev; | ||
| 587 | } | ||
| 588 | constexpr Thread* GetNext() const { | ||
| 589 | return this->next; | ||
| 590 | } | ||
| 591 | constexpr void SetPrev(Thread* thread) { | ||
| 592 | this->prev = thread; | ||
| 593 | } | ||
| 594 | constexpr void SetNext(Thread* thread) { | ||
| 595 | this->next = thread; | ||
| 596 | } | ||
| 597 | |||
| 598 | private: | ||
| 599 | Thread* prev{}; | ||
| 600 | Thread* next{}; | ||
| 601 | }; | ||
| 602 | |||
| 603 | QueueEntry& GetPriorityQueueEntry(s32 core) { | ||
| 604 | return this->per_core_priority_queue_entry[core]; | ||
| 605 | } | ||
| 606 | |||
| 607 | const QueueEntry& GetPriorityQueueEntry(s32 core) const { | ||
| 608 | return this->per_core_priority_queue_entry[core]; | ||
| 609 | } | ||
| 610 | |||
| 611 | s32 GetDisableDispatchCount() const { | ||
| 612 | return disable_count; | ||
| 613 | } | ||
| 614 | |||
| 615 | void DisableDispatch() { | ||
| 616 | ASSERT(GetDisableDispatchCount() >= 0); | ||
| 617 | disable_count++; | ||
| 618 | } | ||
| 619 | |||
| 620 | void EnableDispatch() { | ||
| 621 | ASSERT(GetDisableDispatchCount() > 0); | ||
| 622 | disable_count--; | ||
| 623 | } | ||
| 624 | |||
| 576 | private: | 625 | private: |
| 577 | friend class GlobalScheduler; | 626 | friend class GlobalSchedulerContext; |
| 578 | friend class Scheduler; | 627 | friend class KScheduler; |
| 628 | friend class Process; | ||
| 579 | 629 | ||
| 580 | void SetSchedulingStatus(ThreadSchedStatus new_status); | 630 | void SetSchedulingStatus(ThreadSchedStatus new_status); |
| 581 | void AddSchedulingFlag(ThreadSchedFlags flag); | 631 | void AddSchedulingFlag(ThreadSchedFlags flag); |
| @@ -586,15 +636,16 @@ private: | |||
| 586 | Common::SpinLock context_guard{}; | 636 | Common::SpinLock context_guard{}; |
| 587 | ThreadContext32 context_32{}; | 637 | ThreadContext32 context_32{}; |
| 588 | ThreadContext64 context_64{}; | 638 | ThreadContext64 context_64{}; |
| 589 | std::unique_ptr<Core::ARM_Interface> arm_interface{}; | ||
| 590 | std::shared_ptr<Common::Fiber> host_context{}; | 639 | std::shared_ptr<Common::Fiber> host_context{}; |
| 591 | 640 | ||
| 592 | u64 thread_id = 0; | ||
| 593 | |||
| 594 | ThreadStatus status = ThreadStatus::Dormant; | 641 | ThreadStatus status = ThreadStatus::Dormant; |
| 642 | u32 scheduling_state = 0; | ||
| 643 | |||
| 644 | u64 thread_id = 0; | ||
| 595 | 645 | ||
| 596 | VAddr entry_point = 0; | 646 | VAddr entry_point = 0; |
| 597 | VAddr stack_top = 0; | 647 | VAddr stack_top = 0; |
| 648 | std::atomic_int disable_count = 0; | ||
| 598 | 649 | ||
| 599 | ThreadType type; | 650 | ThreadType type; |
| 600 | 651 | ||
| @@ -608,9 +659,8 @@ private: | |||
| 608 | u32 current_priority = 0; | 659 | u32 current_priority = 0; |
| 609 | 660 | ||
| 610 | u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. | 661 | u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. |
| 611 | u64 last_running_ticks = 0; ///< CPU tick when thread was last running | 662 | s64 schedule_count{}; |
| 612 | u64 yield_count = 0; ///< Number of redundant yields carried by this thread. | 663 | s64 last_scheduled_tick{}; |
| 613 | ///< a redundant yield is one where no scheduling is changed | ||
| 614 | 664 | ||
| 615 | s32 processor_id = 0; | 665 | s32 processor_id = 0; |
| 616 | 666 | ||
| @@ -652,16 +702,16 @@ private: | |||
| 652 | Handle hle_time_event; | 702 | Handle hle_time_event; |
| 653 | SynchronizationObject* hle_object; | 703 | SynchronizationObject* hle_object; |
| 654 | 704 | ||
| 655 | Scheduler* scheduler = nullptr; | 705 | KScheduler* scheduler = nullptr; |
| 706 | |||
| 707 | std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{}; | ||
| 656 | 708 | ||
| 657 | u32 ideal_core{0xFFFFFFFF}; | 709 | u32 ideal_core{0xFFFFFFFF}; |
| 658 | u64 affinity_mask{0x1}; | 710 | KAffinityMask affinity_mask{}; |
| 659 | 711 | ||
| 660 | s32 ideal_core_override = -1; | 712 | s32 ideal_core_override = -1; |
| 661 | u64 affinity_mask_override = 0x1; | ||
| 662 | u32 affinity_override_count = 0; | 713 | u32 affinity_override_count = 0; |
| 663 | 714 | ||
| 664 | u32 scheduling_state = 0; | ||
| 665 | u32 pausing_state = 0; | 715 | u32 pausing_state = 0; |
| 666 | bool is_running = false; | 716 | bool is_running = false; |
| 667 | bool is_waiting_on_sync = false; | 717 | bool is_waiting_on_sync = false; |