diff options
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 78 |
1 files changed, 17 insertions, 61 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 71bd466cf..f9828bc43 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -52,7 +52,7 @@ namespace Kernel { | |||
| 52 | 52 | ||
| 53 | struct KernelCore::Impl { | 53 | struct KernelCore::Impl { |
| 54 | explicit Impl(Core::System& system_, KernelCore& kernel_) | 54 | explicit Impl(Core::System& system_, KernelCore& kernel_) |
| 55 | : time_manager{system_}, object_list_container{kernel_}, | 55 | : time_manager{system_}, |
| 56 | service_threads_manager{1, "yuzu:ServiceThreadsManager"}, system{system_} {} | 56 | service_threads_manager{1, "yuzu:ServiceThreadsManager"}, system{system_} {} |
| 57 | 57 | ||
| 58 | void SetMulticore(bool is_multi) { | 58 | void SetMulticore(bool is_multi) { |
| @@ -60,6 +60,7 @@ struct KernelCore::Impl { | |||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | void Initialize(KernelCore& kernel) { | 62 | void Initialize(KernelCore& kernel) { |
| 63 | global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel); | ||
| 63 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); | 64 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); |
| 64 | global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); | 65 | global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); |
| 65 | global_handle_table->Initialize(KHandleTable::MaxTableSize); | 66 | global_handle_table->Initialize(KHandleTable::MaxTableSize); |
| @@ -76,7 +77,7 @@ struct KernelCore::Impl { | |||
| 76 | // Initialize kernel memory and resources. | 77 | // Initialize kernel memory and resources. |
| 77 | InitializeSystemResourceLimit(kernel, system.CoreTiming()); | 78 | InitializeSystemResourceLimit(kernel, system.CoreTiming()); |
| 78 | InitializeMemoryLayout(); | 79 | InitializeMemoryLayout(); |
| 79 | InitializePageSlab(); | 80 | Init::InitializeKPageBufferSlabHeap(system); |
| 80 | InitializeSchedulers(); | 81 | InitializeSchedulers(); |
| 81 | InitializeSuspendThreads(); | 82 | InitializeSuspendThreads(); |
| 82 | InitializePreemption(kernel); | 83 | InitializePreemption(kernel); |
| @@ -107,19 +108,6 @@ struct KernelCore::Impl { | |||
| 107 | for (auto* server_port : server_ports_) { | 108 | for (auto* server_port : server_ports_) { |
| 108 | server_port->Close(); | 109 | server_port->Close(); |
| 109 | } | 110 | } |
| 110 | // Close all open server sessions. | ||
| 111 | std::unordered_set<KServerSession*> server_sessions_; | ||
| 112 | { | ||
| 113 | std::lock_guard lk(server_sessions_lock); | ||
| 114 | server_sessions_ = server_sessions; | ||
| 115 | server_sessions.clear(); | ||
| 116 | } | ||
| 117 | for (auto* server_session : server_sessions_) { | ||
| 118 | server_session->Close(); | ||
| 119 | } | ||
| 120 | |||
| 121 | // Ensure that the object list container is finalized and properly shutdown. | ||
| 122 | object_list_container.Finalize(); | ||
| 123 | 111 | ||
| 124 | // Ensures all service threads gracefully shutdown. | 112 | // Ensures all service threads gracefully shutdown. |
| 125 | ClearServiceThreads(); | 113 | ClearServiceThreads(); |
| @@ -194,11 +182,15 @@ struct KernelCore::Impl { | |||
| 194 | { | 182 | { |
| 195 | std::lock_guard lk(registered_objects_lock); | 183 | std::lock_guard lk(registered_objects_lock); |
| 196 | if (registered_objects.size()) { | 184 | if (registered_objects.size()) { |
| 197 | LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", | 185 | LOG_DEBUG(Kernel, "{} kernel objects were dangling on shutdown!", |
| 198 | registered_objects.size()); | 186 | registered_objects.size()); |
| 199 | registered_objects.clear(); | 187 | registered_objects.clear(); |
| 200 | } | 188 | } |
| 201 | } | 189 | } |
| 190 | |||
| 191 | // Ensure that the object list container is finalized and properly shutdown. | ||
| 192 | global_object_list_container->Finalize(); | ||
| 193 | global_object_list_container.reset(); | ||
| 202 | } | 194 | } |
| 203 | 195 | ||
| 204 | void InitializePhysicalCores() { | 196 | void InitializePhysicalCores() { |
| @@ -291,15 +283,16 @@ struct KernelCore::Impl { | |||
| 291 | 283 | ||
| 292 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time | 284 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time |
| 293 | KThread* GetHostDummyThread() { | 285 | KThread* GetHostDummyThread() { |
| 294 | auto make_thread = [this]() { | 286 | auto initialize = [this](KThread* thread) { |
| 295 | KThread* thread = KThread::Create(system.Kernel()); | ||
| 296 | ASSERT(KThread::InitializeDummyThread(thread).IsSuccess()); | 287 | ASSERT(KThread::InitializeDummyThread(thread).IsSuccess()); |
| 297 | thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); | 288 | thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); |
| 298 | return thread; | 289 | return thread; |
| 299 | }; | 290 | }; |
| 300 | 291 | ||
| 301 | thread_local KThread* saved_thread = make_thread(); | 292 | thread_local auto raw_thread = KThread(system.Kernel()); |
| 302 | return saved_thread; | 293 | thread_local auto thread = initialize(&raw_thread); |
| 294 | |||
| 295 | return thread; | ||
| 303 | } | 296 | } |
| 304 | 297 | ||
| 305 | /// Registers a CPU core thread by allocating a host thread ID for it | 298 | /// Registers a CPU core thread by allocating a host thread ID for it |
| @@ -660,22 +653,6 @@ struct KernelCore::Impl { | |||
| 660 | time_phys_addr, time_size, "Time:SharedMemory"); | 653 | time_phys_addr, time_size, "Time:SharedMemory"); |
| 661 | } | 654 | } |
| 662 | 655 | ||
| 663 | void InitializePageSlab() { | ||
| 664 | // Allocate slab heaps | ||
| 665 | user_slab_heap_pages = | ||
| 666 | std::make_unique<KSlabHeap<Page>>(KSlabHeap<Page>::AllocationType::Guest); | ||
| 667 | |||
| 668 | // TODO(ameerj): This should be derived, not hardcoded within the kernel | ||
| 669 | constexpr u64 user_slab_heap_size{0x3de000}; | ||
| 670 | // Reserve slab heaps | ||
| 671 | ASSERT( | ||
| 672 | system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); | ||
| 673 | // Initialize slab heap | ||
| 674 | user_slab_heap_pages->Initialize( | ||
| 675 | system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), | ||
| 676 | user_slab_heap_size); | ||
| 677 | } | ||
| 678 | |||
| 679 | KClientPort* CreateNamedServicePort(std::string name) { | 656 | KClientPort* CreateNamedServicePort(std::string name) { |
| 680 | auto search = service_interface_factory.find(name); | 657 | auto search = service_interface_factory.find(name); |
| 681 | if (search == service_interface_factory.end()) { | 658 | if (search == service_interface_factory.end()) { |
| @@ -713,7 +690,6 @@ struct KernelCore::Impl { | |||
| 713 | } | 690 | } |
| 714 | 691 | ||
| 715 | std::mutex server_ports_lock; | 692 | std::mutex server_ports_lock; |
| 716 | std::mutex server_sessions_lock; | ||
| 717 | std::mutex registered_objects_lock; | 693 | std::mutex registered_objects_lock; |
| 718 | std::mutex registered_in_use_objects_lock; | 694 | std::mutex registered_in_use_objects_lock; |
| 719 | 695 | ||
| @@ -737,14 +713,13 @@ struct KernelCore::Impl { | |||
| 737 | // stores all the objects in place. | 713 | // stores all the objects in place. |
| 738 | std::unique_ptr<KHandleTable> global_handle_table; | 714 | std::unique_ptr<KHandleTable> global_handle_table; |
| 739 | 715 | ||
| 740 | KAutoObjectWithListContainer object_list_container; | 716 | std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container; |
| 741 | 717 | ||
| 742 | /// Map of named ports managed by the kernel, which can be retrieved using | 718 | /// Map of named ports managed by the kernel, which can be retrieved using |
| 743 | /// the ConnectToPort SVC. | 719 | /// the ConnectToPort SVC. |
| 744 | std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; | 720 | std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; |
| 745 | NamedPortTable named_ports; | 721 | NamedPortTable named_ports; |
| 746 | std::unordered_set<KServerPort*> server_ports; | 722 | std::unordered_set<KServerPort*> server_ports; |
| 747 | std::unordered_set<KServerSession*> server_sessions; | ||
| 748 | std::unordered_set<KAutoObject*> registered_objects; | 723 | std::unordered_set<KAutoObject*> registered_objects; |
| 749 | std::unordered_set<KAutoObject*> registered_in_use_objects; | 724 | std::unordered_set<KAutoObject*> registered_in_use_objects; |
| 750 | 725 | ||
| @@ -756,7 +731,6 @@ struct KernelCore::Impl { | |||
| 756 | 731 | ||
| 757 | // Kernel memory management | 732 | // Kernel memory management |
| 758 | std::unique_ptr<KMemoryManager> memory_manager; | 733 | std::unique_ptr<KMemoryManager> memory_manager; |
| 759 | std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; | ||
| 760 | 734 | ||
| 761 | // Shared memory for services | 735 | // Shared memory for services |
| 762 | Kernel::KSharedMemory* hid_shared_mem{}; | 736 | Kernel::KSharedMemory* hid_shared_mem{}; |
| @@ -915,11 +889,11 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { | |||
| 915 | } | 889 | } |
| 916 | 890 | ||
| 917 | KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { | 891 | KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { |
| 918 | return impl->object_list_container; | 892 | return *impl->global_object_list_container; |
| 919 | } | 893 | } |
| 920 | 894 | ||
| 921 | const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { | 895 | const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { |
| 922 | return impl->object_list_container; | 896 | return *impl->global_object_list_container; |
| 923 | } | 897 | } |
| 924 | 898 | ||
| 925 | void KernelCore::InvalidateAllInstructionCaches() { | 899 | void KernelCore::InvalidateAllInstructionCaches() { |
| @@ -949,16 +923,6 @@ KClientPort* KernelCore::CreateNamedServicePort(std::string name) { | |||
| 949 | return impl->CreateNamedServicePort(std::move(name)); | 923 | return impl->CreateNamedServicePort(std::move(name)); |
| 950 | } | 924 | } |
| 951 | 925 | ||
| 952 | void KernelCore::RegisterServerSession(KServerSession* server_session) { | ||
| 953 | std::lock_guard lk(impl->server_sessions_lock); | ||
| 954 | impl->server_sessions.insert(server_session); | ||
| 955 | } | ||
| 956 | |||
| 957 | void KernelCore::UnregisterServerSession(KServerSession* server_session) { | ||
| 958 | std::lock_guard lk(impl->server_sessions_lock); | ||
| 959 | impl->server_sessions.erase(server_session); | ||
| 960 | } | ||
| 961 | |||
| 962 | void KernelCore::RegisterKernelObject(KAutoObject* object) { | 926 | void KernelCore::RegisterKernelObject(KAutoObject* object) { |
| 963 | std::lock_guard lk(impl->registered_objects_lock); | 927 | std::lock_guard lk(impl->registered_objects_lock); |
| 964 | impl->registered_objects.insert(object); | 928 | impl->registered_objects.insert(object); |
| @@ -1031,14 +995,6 @@ const KMemoryManager& KernelCore::MemoryManager() const { | |||
| 1031 | return *impl->memory_manager; | 995 | return *impl->memory_manager; |
| 1032 | } | 996 | } |
| 1033 | 997 | ||
| 1034 | KSlabHeap<Page>& KernelCore::GetUserSlabHeapPages() { | ||
| 1035 | return *impl->user_slab_heap_pages; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | const KSlabHeap<Page>& KernelCore::GetUserSlabHeapPages() const { | ||
| 1039 | return *impl->user_slab_heap_pages; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | Kernel::KSharedMemory& KernelCore::GetHidSharedMem() { | 998 | Kernel::KSharedMemory& KernelCore::GetHidSharedMem() { |
| 1043 | return *impl->hid_shared_mem; | 999 | return *impl->hid_shared_mem; |
| 1044 | } | 1000 | } |