summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2021-04-09 22:42:23 -0700
committerGravatar bunnei2021-05-05 16:40:51 -0700
commit89edbe8aa20d278d6f2c5ab735163f0d96ff88d2 (patch)
tree568023bd7dbb880730c2cbbcbafe025045fe2f7b /src/core
parenthle: kernel: Move slab heap management to KernelCore. (diff)
downloadyuzu-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')
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp16
-rw-r--r--src/core/hle/kernel/k_scheduler.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp50
-rw-r--r--src/core/hle/kernel/process.cpp2
-rw-r--r--src/core/hle/kernel/slab_helpers.h16
-rw-r--r--src/core/hle/kernel/svc.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp8
-rw-r--r--src/core/hle/service/hid/controllers/npad.h5
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp3
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h2
11 files changed, 53 insertions, 59 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index f050a8d4b..b5bc903cd 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -233,7 +233,7 @@ struct System::Impl {
233 } 233 }
234 234
235 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); 235 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
236 auto main_process = Kernel::Process::CreateWithKernel(system.Kernel()); 236 auto main_process = Kernel::Process::Create(system.Kernel());
237 ASSERT(Kernel::Process::Initialize(main_process, system, "main", 237 ASSERT(Kernel::Process::Initialize(main_process, system, "main",
238 Kernel::Process::ProcessType::Userland) 238 Kernel::Process::ProcessType::Userland)
239 .IsSuccess()); 239 .IsSuccess());
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
620KScheduler::~KScheduler() { 620KScheduler::~KScheduler() {
621 idle_thread->Close(); 621 if (idle_thread) {
622 idle_thread->Close();
623 idle_thread = nullptr;
624 }
622} 625}
623 626
624KThread* KScheduler::GetCurrentThread() const { 627KThread* 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
631u64 KScheduler::GetLastContextSwitchTicks() const { 634u64 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
796void KScheduler::Initialize() { 799void 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
68private: 68private:
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.
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 753875d6e..77768ca7d 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -253,8 +253,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
253void Controller_NPad::OnInit() { 253void Controller_NPad::OnInit() {
254 auto& kernel = system.Kernel(); 254 auto& kernel = system.Kernel();
255 for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { 255 for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
256 styleset_changed_events[i] = std::make_unique<Kernel::KEvent>(kernel); 256 styleset_changed_events[i] = Kernel::KEvent::Create(kernel);
257 Kernel::KAutoObject::Create(styleset_changed_events[i].get());
258 styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i)); 257 styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i));
259 } 258 }
260 259
@@ -341,6 +340,11 @@ void Controller_NPad::OnRelease() {
341 VibrateControllerAtIndex(npad_idx, device_idx, {}); 340 VibrateControllerAtIndex(npad_idx, device_idx, {});
342 } 341 }
343 } 342 }
343
344 for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
345 styleset_changed_events[i]->Close();
346 styleset_changed_events[i] = nullptr;
347 }
344} 348}
345 349
346void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { 350void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 515cf7c37..b3de272b6 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -573,8 +573,9 @@ private:
573 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; 573 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
574 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; 574 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
575 // Each controller should have their own styleset changed event 575 // Each controller should have their own styleset changed event
576 std::array<std::unique_ptr<Kernel::KEvent>, 10> styleset_changed_events; 576 std::array<Kernel::KEvent*, 10> styleset_changed_events{};
577 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints; 577 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10>
578 last_vibration_timepoints{};
578 std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; 579 std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
579 bool permit_vibration_session_enabled{false}; 580 bool permit_vibration_session_enabled{false};
580 std::array<std::array<bool, 2>, 10> vibration_devices_mounted{}; 581 std::array<std::array<bool, 2>, 10> vibration_devices_mounted{};
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 64bdb0722..2fbf61cd6 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -42,8 +42,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
42Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { 42Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} {
43 auto& kernel = system.Kernel(); 43 auto& kernel = system.Kernel();
44 for (u32 i = 0; i < MaxNvEvents; i++) { 44 for (u32 i = 0; i < MaxNvEvents; i++) {
45 events_interface.events[i].event = std::make_unique<Kernel::KEvent>(kernel); 45 events_interface.events[i].event = Kernel::KEvent::Create(kernel);
46 Kernel::KAutoObject::Create(events_interface.events[i].event.get());
47 events_interface.events[i].event->Initialize(fmt::format("NVDRV::NvEvent_{}", i)); 46 events_interface.events[i].event->Initialize(fmt::format("NVDRV::NvEvent_{}", i));
48 events_interface.status[i] = EventState::Free; 47 events_interface.status[i] = EventState::Free;
49 events_interface.registered[i] = false; 48 events_interface.registered[i] = false;
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 76f77cbb1..ea5dbbdf9 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -35,7 +35,7 @@ class nvdevice;
35 35
36/// Represents an Nvidia event 36/// Represents an Nvidia event
37struct NvEvent { 37struct NvEvent {
38 std::unique_ptr<Kernel::KEvent> event; 38 Kernel::KEvent* event{};
39 Fence fence{}; 39 Fence fence{};
40}; 40};
41 41