diff options
| author | 2021-04-09 22:42:23 -0700 | |
|---|---|---|
| committer | 2021-05-05 16:40:51 -0700 | |
| commit | 89edbe8aa20d278d6f2c5ab735163f0d96ff88d2 (patch) | |
| tree | 568023bd7dbb880730c2cbbcbafe025045fe2f7b /src/core/hle/kernel | |
| parent | hle: kernel: Move slab heap management to KernelCore. (diff) | |
| download | yuzu-89edbe8aa20d278d6f2c5ab735163f0d96ff88d2.tar.gz yuzu-89edbe8aa20d278d6f2c5ab735163f0d96ff88d2.tar.xz yuzu-89edbe8aa20d278d6f2c5ab735163f0d96ff88d2.zip | |
hle: kernel: Refactor several threads/events/sharedmemory to use slab heaps.
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 50 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/slab_helpers.h | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 4 |
6 files changed, 41 insertions, 51 deletions
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 1feda9303..38c6b50fa 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -618,14 +618,17 @@ KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core | |||
| 618 | } | 618 | } |
| 619 | 619 | ||
| 620 | KScheduler::~KScheduler() { | 620 | KScheduler::~KScheduler() { |
| 621 | idle_thread->Close(); | 621 | if (idle_thread) { |
| 622 | idle_thread->Close(); | ||
| 623 | idle_thread = nullptr; | ||
| 624 | } | ||
| 622 | } | 625 | } |
| 623 | 626 | ||
| 624 | KThread* KScheduler::GetCurrentThread() const { | 627 | KThread* KScheduler::GetCurrentThread() const { |
| 625 | if (auto result = current_thread.load(); result) { | 628 | if (auto result = current_thread.load(); result) { |
| 626 | return result; | 629 | return result; |
| 627 | } | 630 | } |
| 628 | return idle_thread.get(); | 631 | return idle_thread; |
| 629 | } | 632 | } |
| 630 | 633 | ||
| 631 | u64 KScheduler::GetLastContextSwitchTicks() const { | 634 | u64 KScheduler::GetLastContextSwitchTicks() const { |
| @@ -710,7 +713,7 @@ void KScheduler::ScheduleImpl() { | |||
| 710 | 713 | ||
| 711 | // We never want to schedule a null thread, so use the idle thread if we don't have a next. | 714 | // We never want to schedule a null thread, so use the idle thread if we don't have a next. |
| 712 | if (next_thread == nullptr) { | 715 | if (next_thread == nullptr) { |
| 713 | next_thread = idle_thread.get(); | 716 | next_thread = idle_thread; |
| 714 | } | 717 | } |
| 715 | 718 | ||
| 716 | // If we're not actually switching thread, there's nothing to do. | 719 | // If we're not actually switching thread, there's nothing to do. |
| @@ -771,7 +774,7 @@ void KScheduler::SwitchToCurrent() { | |||
| 771 | break; | 774 | break; |
| 772 | } | 775 | } |
| 773 | } | 776 | } |
| 774 | auto thread = next_thread ? next_thread : idle_thread.get(); | 777 | auto thread = next_thread ? next_thread : idle_thread; |
| 775 | Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext()); | 778 | Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext()); |
| 776 | } while (!is_switch_pending()); | 779 | } while (!is_switch_pending()); |
| 777 | } | 780 | } |
| @@ -794,9 +797,8 @@ void KScheduler::UpdateLastContextSwitchTime(KThread* thread, Process* process) | |||
| 794 | } | 797 | } |
| 795 | 798 | ||
| 796 | void KScheduler::Initialize() { | 799 | void KScheduler::Initialize() { |
| 797 | idle_thread = std::make_unique<KThread>(system.Kernel()); | 800 | idle_thread = KThread::Create(system.Kernel()); |
| 798 | KAutoObject::Create(idle_thread.get()); | 801 | ASSERT(KThread::InitializeIdleThread(system, idle_thread, core_id).IsSuccess()); |
| 799 | ASSERT(KThread::InitializeIdleThread(system, idle_thread.get(), core_id).IsSuccess()); | ||
| 800 | idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); | 802 | idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); |
| 801 | } | 803 | } |
| 802 | 804 | ||
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 8cb5f6f36..01387b892 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h | |||
| @@ -51,7 +51,7 @@ public: | |||
| 51 | 51 | ||
| 52 | /// Returns true if the scheduler is idle | 52 | /// Returns true if the scheduler is idle |
| 53 | [[nodiscard]] bool IsIdle() const { | 53 | [[nodiscard]] bool IsIdle() const { |
| 54 | return GetCurrentThread() == idle_thread.get(); | 54 | return GetCurrentThread() == idle_thread; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /// Gets the timestamp for the last context switch in ticks. | 57 | /// Gets the timestamp for the last context switch in ticks. |
| @@ -173,7 +173,7 @@ private: | |||
| 173 | KThread* prev_thread{}; | 173 | KThread* prev_thread{}; |
| 174 | std::atomic<KThread*> current_thread{}; | 174 | std::atomic<KThread*> current_thread{}; |
| 175 | 175 | ||
| 176 | std::unique_ptr<KThread> idle_thread; | 176 | KThread* idle_thread{}; |
| 177 | 177 | ||
| 178 | std::shared_ptr<Common::Fiber> switch_fiber{}; | 178 | std::shared_ptr<Common::Fiber> switch_fiber{}; |
| 179 | 179 | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 43bce1863..1b7ba39f4 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -102,15 +102,21 @@ struct KernelCore::Impl { | |||
| 102 | next_user_process_id = Process::ProcessIDMin; | 102 | next_user_process_id = Process::ProcessIDMin; |
| 103 | next_thread_id = 1; | 103 | next_thread_id = 1; |
| 104 | 104 | ||
| 105 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 105 | for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 106 | if (suspend_threads[i]) { | 106 | if (suspend_threads[core_id]) { |
| 107 | suspend_threads[i]->Close(); | 107 | suspend_threads[core_id]->Close(); |
| 108 | suspend_threads[core_id] = nullptr; | ||
| 108 | } | 109 | } |
| 110 | |||
| 111 | schedulers[core_id].reset(); | ||
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | cores.clear(); | 114 | cores.clear(); |
| 112 | 115 | ||
| 113 | current_process = nullptr; | 116 | if (current_process) { |
| 117 | current_process->Close(); | ||
| 118 | current_process = nullptr; | ||
| 119 | } | ||
| 114 | 120 | ||
| 115 | global_handle_table.Clear(); | 121 | global_handle_table.Clear(); |
| 116 | 122 | ||
| @@ -195,10 +201,9 @@ struct KernelCore::Impl { | |||
| 195 | 201 | ||
| 196 | void InitializeSuspendThreads() { | 202 | void InitializeSuspendThreads() { |
| 197 | for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 203 | for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 198 | suspend_threads[core_id] = std::make_unique<KThread>(system.Kernel()); | 204 | suspend_threads[core_id] = KThread::Create(system.Kernel()); |
| 199 | KAutoObject::Create(suspend_threads[core_id].get()); | 205 | ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, |
| 200 | ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id].get(), {}, | 206 | core_id) |
| 201 | {}, core_id) | ||
| 202 | .IsSuccess()); | 207 | .IsSuccess()); |
| 203 | suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); | 208 | suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); |
| 204 | } | 209 | } |
| @@ -577,15 +582,10 @@ struct KernelCore::Impl { | |||
| 577 | const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; | 582 | const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; |
| 578 | const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; | 583 | const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; |
| 579 | 584 | ||
| 580 | hid_shared_mem = std::make_unique<KSharedMemory>(system.Kernel()); | 585 | hid_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 581 | font_shared_mem = std::make_unique<KSharedMemory>(system.Kernel()); | 586 | font_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 582 | irs_shared_mem = std::make_unique<KSharedMemory>(system.Kernel()); | 587 | irs_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 583 | time_shared_mem = std::make_unique<KSharedMemory>(system.Kernel()); | 588 | time_shared_mem = KSharedMemory::Create(system.Kernel()); |
| 584 | |||
| 585 | KAutoObject::Create(hid_shared_mem.get()); | ||
| 586 | KAutoObject::Create(font_shared_mem.get()); | ||
| 587 | KAutoObject::Create(irs_shared_mem.get()); | ||
| 588 | KAutoObject::Create(time_shared_mem.get()); | ||
| 589 | 589 | ||
| 590 | hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, | 590 | hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, |
| 591 | {hid_phys_addr, hid_size / PageSize}, KMemoryPermission::None, | 591 | {hid_phys_addr, hid_size / PageSize}, KMemoryPermission::None, |
| @@ -656,10 +656,10 @@ struct KernelCore::Impl { | |||
| 656 | std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; | 656 | std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; |
| 657 | 657 | ||
| 658 | // Shared memory for services | 658 | // Shared memory for services |
| 659 | std::unique_ptr<Kernel::KSharedMemory> hid_shared_mem; | 659 | Kernel::KSharedMemory* hid_shared_mem{}; |
| 660 | std::unique_ptr<Kernel::KSharedMemory> font_shared_mem; | 660 | Kernel::KSharedMemory* font_shared_mem{}; |
| 661 | std::unique_ptr<Kernel::KSharedMemory> irs_shared_mem; | 661 | Kernel::KSharedMemory* irs_shared_mem{}; |
| 662 | std::unique_ptr<Kernel::KSharedMemory> time_shared_mem; | 662 | Kernel::KSharedMemory* time_shared_mem{}; |
| 663 | 663 | ||
| 664 | // Threads used for services | 664 | // Threads used for services |
| 665 | std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; | 665 | std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; |
| @@ -668,7 +668,7 @@ struct KernelCore::Impl { | |||
| 668 | // the release of itself | 668 | // the release of itself |
| 669 | std::unique_ptr<Common::ThreadWorker> service_thread_manager; | 669 | std::unique_ptr<Common::ThreadWorker> service_thread_manager; |
| 670 | 670 | ||
| 671 | std::array<std::unique_ptr<KThread>, Core::Hardware::NUM_CPU_CORES> suspend_threads; | 671 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; |
| 672 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | 672 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; |
| 673 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 673 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| 674 | 674 | ||
| @@ -938,9 +938,9 @@ void KernelCore::Suspend(bool in_suspention) { | |||
| 938 | { | 938 | { |
| 939 | KScopedSchedulerLock lock(*this); | 939 | KScopedSchedulerLock lock(*this); |
| 940 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; | 940 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; |
| 941 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | 941 | for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 942 | impl->suspend_threads[i]->SetState(state); | 942 | impl->suspend_threads[core_id]->SetState(state); |
| 943 | impl->suspend_threads[i]->SetWaitReasonForDebugging( | 943 | impl->suspend_threads[core_id]->SetWaitReasonForDebugging( |
| 944 | ThreadWaitReasonForDebugging::Suspended); | 944 | ThreadWaitReasonForDebugging::Suspended); |
| 945 | } | 945 | } |
| 946 | } | 946 | } |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index fe4558648..8088c634f 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -41,7 +41,7 @@ void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, | |||
| 41 | const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); | 41 | const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); |
| 42 | ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); | 42 | ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); |
| 43 | 43 | ||
| 44 | KThread* thread = KThread::CreateWithKernel(system.Kernel()); | 44 | KThread* thread = KThread::Create(system.Kernel()); |
| 45 | ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, | 45 | ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, |
| 46 | owner_process.GetIdealCoreId(), &owner_process) | 46 | owner_process.GetIdealCoreId(), &owner_process) |
| 47 | .IsSuccess()); | 47 | .IsSuccess()); |
diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h index 4f23ddabf..66954b6b2 100644 --- a/src/core/hle/kernel/slab_helpers.h +++ b/src/core/hle/kernel/slab_helpers.h | |||
| @@ -67,10 +67,6 @@ class KAutoObjectWithSlabHeapAndContainer : public Base { | |||
| 67 | 67 | ||
| 68 | private: | 68 | private: |
| 69 | static Derived* Allocate(KernelCore& kernel) { | 69 | static Derived* Allocate(KernelCore& kernel) { |
| 70 | return kernel.SlabHeap<Derived>().Allocate(); | ||
| 71 | } | ||
| 72 | |||
| 73 | static Derived* AllocateWithKernel(KernelCore& kernel) { | ||
| 74 | return kernel.SlabHeap<Derived>().AllocateWithKernel(kernel); | 70 | return kernel.SlabHeap<Derived>().AllocateWithKernel(kernel); |
| 75 | } | 71 | } |
| 76 | 72 | ||
| @@ -120,16 +116,8 @@ public: | |||
| 120 | kernel.ObjectListContainer().Initialize(); | 116 | kernel.ObjectListContainer().Initialize(); |
| 121 | } | 117 | } |
| 122 | 118 | ||
| 123 | static Derived* Create() { | 119 | static Derived* Create(KernelCore& kernel) { |
| 124 | Derived* obj = Allocate(); | 120 | Derived* obj = Allocate(kernel); |
| 125 | if (obj != nullptr) { | ||
| 126 | KAutoObject::Create(obj); | ||
| 127 | } | ||
| 128 | return obj; | ||
| 129 | } | ||
| 130 | |||
| 131 | static Derived* CreateWithKernel(KernelCore& kernel) { | ||
| 132 | Derived* obj = AllocateWithKernel(kernel); | ||
| 133 | if (obj != nullptr) { | 121 | if (obj != nullptr) { |
| 134 | KAutoObject::Create(obj); | 122 | KAutoObject::Create(obj); |
| 135 | } | 123 | } |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b143a51c7..8050359be 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1431,7 +1431,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1431 | } | 1431 | } |
| 1432 | 1432 | ||
| 1433 | // Create the thread. | 1433 | // Create the thread. |
| 1434 | KThread* thread = KThread::CreateWithKernel(kernel); | 1434 | KThread* thread = KThread::Create(kernel); |
| 1435 | if (!thread) { | 1435 | if (!thread) { |
| 1436 | LOG_ERROR(Kernel_SVC, "Unable to create new threads. Thread creation limit reached."); | 1436 | LOG_ERROR(Kernel_SVC, "Unable to create new threads. Thread creation limit reached."); |
| 1437 | return ResultOutOfResource; | 1437 | return ResultOutOfResource; |
| @@ -1953,7 +1953,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o | |||
| 1953 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 1953 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); |
| 1954 | 1954 | ||
| 1955 | // Create a new event. | 1955 | // Create a new event. |
| 1956 | KEvent* event = KEvent::CreateWithKernel(kernel); | 1956 | KEvent* event = KEvent::Create(kernel); |
| 1957 | R_UNLESS(event != nullptr, ResultOutOfResource); | 1957 | R_UNLESS(event != nullptr, ResultOutOfResource); |
| 1958 | 1958 | ||
| 1959 | // Initialize the event. | 1959 | // Initialize the event. |