diff options
| author | 2020-12-20 20:57:54 -0800 | |
|---|---|---|
| committer | 2020-12-20 20:57:54 -0800 | |
| commit | 1279c7ce7afd3d1bf2b4e33aa922158acf2cd060 (patch) | |
| tree | 6db8088caed2bd957187e4730f51424325038fa5 /src/core/hle/kernel/thread.h | |
| parent | Merge pull request #5201 from ameerj/bufferq-refactor (diff) | |
| parent | hle: kernel: Process: Various style fixes based on code review feedback. (diff) | |
| download | yuzu-1279c7ce7afd3d1bf2b4e33aa922158acf2cd060.tar.gz yuzu-1279c7ce7afd3d1bf2b4e33aa922158acf2cd060.tar.xz yuzu-1279c7ce7afd3d1bf2b4e33aa922158acf2cd060.zip | |
Merge pull request #5131 from bunnei/scheduler-rewrite
Rewrite Kernel scheduler based on Atmosphere
Diffstat (limited to 'src/core/hle/kernel/thread.h')
| -rw-r--r-- | src/core/hle/kernel/thread.h | 114 |
1 files changed, 85 insertions, 29 deletions
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index a75071e9b..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 |
| @@ -345,8 +347,12 @@ public: | |||
| 345 | 347 | ||
| 346 | void SetStatus(ThreadStatus new_status); | 348 | void SetStatus(ThreadStatus new_status); |
| 347 | 349 | ||
| 348 | u64 GetLastRunningTicks() const { | 350 | s64 GetLastScheduledTick() const { |
| 349 | return last_running_ticks; | 351 | return this->last_scheduled_tick; |
| 352 | } | ||
| 353 | |||
| 354 | void SetLastScheduledTick(s64 tick) { | ||
| 355 | this->last_scheduled_tick = tick; | ||
| 350 | } | 356 | } |
| 351 | 357 | ||
| 352 | u64 GetTotalCPUTimeTicks() const { | 358 | u64 GetTotalCPUTimeTicks() const { |
| @@ -361,10 +367,18 @@ public: | |||
| 361 | return processor_id; | 367 | return processor_id; |
| 362 | } | 368 | } |
| 363 | 369 | ||
| 370 | s32 GetActiveCore() const { | ||
| 371 | return GetProcessorID(); | ||
| 372 | } | ||
| 373 | |||
| 364 | void SetProcessorID(s32 new_core) { | 374 | void SetProcessorID(s32 new_core) { |
| 365 | processor_id = new_core; | 375 | processor_id = new_core; |
| 366 | } | 376 | } |
| 367 | 377 | ||
| 378 | void SetActiveCore(s32 new_core) { | ||
| 379 | processor_id = new_core; | ||
| 380 | } | ||
| 381 | |||
| 368 | Process* GetOwnerProcess() { | 382 | Process* GetOwnerProcess() { |
| 369 | return owner_process; | 383 | return owner_process; |
| 370 | } | 384 | } |
| @@ -469,7 +483,7 @@ public: | |||
| 469 | return ideal_core; | 483 | return ideal_core; |
| 470 | } | 484 | } |
| 471 | 485 | ||
| 472 | u64 GetAffinityMask() const { | 486 | const KAffinityMask& GetAffinityMask() const { |
| 473 | return affinity_mask; | 487 | return affinity_mask; |
| 474 | } | 488 | } |
| 475 | 489 | ||
| @@ -478,21 +492,12 @@ public: | |||
| 478 | /// Sleeps this thread for the given amount of nanoseconds. | 492 | /// Sleeps this thread for the given amount of nanoseconds. |
| 479 | ResultCode Sleep(s64 nanoseconds); | 493 | ResultCode Sleep(s64 nanoseconds); |
| 480 | 494 | ||
| 481 | /// Yields this thread without rebalancing loads. | 495 | s64 GetYieldScheduleCount() const { |
| 482 | std::pair<ResultCode, bool> YieldSimple(); | 496 | return this->schedule_count; |
| 483 | |||
| 484 | /// Yields this thread and does a load rebalancing. | ||
| 485 | std::pair<ResultCode, bool> YieldAndBalanceLoad(); | ||
| 486 | |||
| 487 | /// Yields this thread and if the core is left idle, loads are rebalanced | ||
| 488 | std::pair<ResultCode, bool> YieldAndWaitForLoadBalancing(); | ||
| 489 | |||
| 490 | void IncrementYieldCount() { | ||
| 491 | yield_count++; | ||
| 492 | } | 497 | } |
| 493 | 498 | ||
| 494 | u64 GetYieldCount() const { | 499 | void SetYieldScheduleCount(s64 count) { |
| 495 | return yield_count; | 500 | this->schedule_count = count; |
| 496 | } | 501 | } |
| 497 | 502 | ||
| 498 | ThreadSchedStatus GetSchedulingStatus() const { | 503 | ThreadSchedStatus GetSchedulingStatus() const { |
| @@ -568,9 +573,59 @@ public: | |||
| 568 | return has_exited; | 573 | return has_exited; |
| 569 | } | 574 | } |
| 570 | 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 | |||
| 571 | private: | 625 | private: |
| 572 | friend class GlobalScheduler; | 626 | friend class GlobalSchedulerContext; |
| 573 | friend class Scheduler; | 627 | friend class KScheduler; |
| 628 | friend class Process; | ||
| 574 | 629 | ||
| 575 | void SetSchedulingStatus(ThreadSchedStatus new_status); | 630 | void SetSchedulingStatus(ThreadSchedStatus new_status); |
| 576 | void AddSchedulingFlag(ThreadSchedFlags flag); | 631 | void AddSchedulingFlag(ThreadSchedFlags flag); |
| @@ -583,12 +638,14 @@ private: | |||
| 583 | ThreadContext64 context_64{}; | 638 | ThreadContext64 context_64{}; |
| 584 | std::shared_ptr<Common::Fiber> host_context{}; | 639 | std::shared_ptr<Common::Fiber> host_context{}; |
| 585 | 640 | ||
| 586 | u64 thread_id = 0; | ||
| 587 | |||
| 588 | ThreadStatus status = ThreadStatus::Dormant; | 641 | ThreadStatus status = ThreadStatus::Dormant; |
| 642 | u32 scheduling_state = 0; | ||
| 643 | |||
| 644 | u64 thread_id = 0; | ||
| 589 | 645 | ||
| 590 | VAddr entry_point = 0; | 646 | VAddr entry_point = 0; |
| 591 | VAddr stack_top = 0; | 647 | VAddr stack_top = 0; |
| 648 | std::atomic_int disable_count = 0; | ||
| 592 | 649 | ||
| 593 | ThreadType type; | 650 | ThreadType type; |
| 594 | 651 | ||
| @@ -602,9 +659,8 @@ private: | |||
| 602 | u32 current_priority = 0; | 659 | u32 current_priority = 0; |
| 603 | 660 | ||
| 604 | u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. | 661 | u64 total_cpu_time_ticks = 0; ///< Total CPU running ticks. |
| 605 | u64 last_running_ticks = 0; ///< CPU tick when thread was last running | 662 | s64 schedule_count{}; |
| 606 | u64 yield_count = 0; ///< Number of redundant yields carried by this thread. | 663 | s64 last_scheduled_tick{}; |
| 607 | ///< a redundant yield is one where no scheduling is changed | ||
| 608 | 664 | ||
| 609 | s32 processor_id = 0; | 665 | s32 processor_id = 0; |
| 610 | 666 | ||
| @@ -646,16 +702,16 @@ private: | |||
| 646 | Handle hle_time_event; | 702 | Handle hle_time_event; |
| 647 | SynchronizationObject* hle_object; | 703 | SynchronizationObject* hle_object; |
| 648 | 704 | ||
| 649 | Scheduler* scheduler = nullptr; | 705 | KScheduler* scheduler = nullptr; |
| 706 | |||
| 707 | std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{}; | ||
| 650 | 708 | ||
| 651 | u32 ideal_core{0xFFFFFFFF}; | 709 | u32 ideal_core{0xFFFFFFFF}; |
| 652 | u64 affinity_mask{0x1}; | 710 | KAffinityMask affinity_mask{}; |
| 653 | 711 | ||
| 654 | s32 ideal_core_override = -1; | 712 | s32 ideal_core_override = -1; |
| 655 | u64 affinity_mask_override = 0x1; | ||
| 656 | u32 affinity_override_count = 0; | 713 | u32 affinity_override_count = 0; |
| 657 | 714 | ||
| 658 | u32 scheduling_state = 0; | ||
| 659 | u32 pausing_state = 0; | 715 | u32 pausing_state = 0; |
| 660 | bool is_running = false; | 716 | bool is_running = false; |
| 661 | bool is_waiting_on_sync = false; | 717 | bool is_waiting_on_sync = false; |