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.h120
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
28namespace Kernel { 30namespace Kernel {
29 31
30class GlobalScheduler; 32class GlobalSchedulerContext;
31class KernelCore; 33class KernelCore;
32class Process; 34class Process;
33class Scheduler; 35class KScheduler;
34 36
35enum ThreadPriority : u32 { 37enum 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
74enum class ThreadStatus { 76enum 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
576private: 625private:
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;