diff options
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index c0ff287a6..b20c2d13a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -28,17 +28,17 @@ #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory/memory_layout.h" #include "core/hle/kernel/memory/memory_manager.h" #include "core/hle/kernel/memory/slab_heap.h" #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" #include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/shared_memory.h" -#include "core/hle/kernel/thread.h" #include "core/hle/kernel/time_manager.h" #include "core/hle/lock.h" #include "core/hle/result.h" @@ -57,14 +57,16 @@ struct KernelCore::Impl { } void Initialize(KernelCore& kernel) { + global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); + RegisterHostThread(); - global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); service_thread_manager = std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); + is_phantom_mode_for_singlecore = false; InitializePhysicalCores(); - InitializeSystemResourceLimit(kernel); + InitializeSystemResourceLimit(kernel, system); InitializeMemoryLayout(); InitializePreemption(kernel); InitializeSchedulers(); @@ -116,32 +118,32 @@ struct KernelCore::Impl { void InitializePhysicalCores() { exclusive_monitor = Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { + for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { schedulers[i] = std::make_unique<Kernel::KScheduler>(system, i); cores.emplace_back(i, system, *schedulers[i], interrupts); } } void InitializeSchedulers() { - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { + for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { cores[i].Scheduler().Initialize(); } } // Creates the default system resource limit - void InitializeSystemResourceLimit(KernelCore& kernel) { - system_resource_limit = ResourceLimit::Create(kernel); + void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) { + system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); // If setting the default system values fails, then something seriously wrong has occurred. - ASSERT(system_resource_limit->SetLimitValue(ResourceType::PhysicalMemory, 0x100000000) + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) .IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::Threads, 800).IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::Events, 700).IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::TransferMemory, 200).IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) + .IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 900).IsSuccess()); - if (!system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0) || - !system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0x60000)) { + if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 0x60000)) { UNREACHABLE(); } } @@ -168,11 +170,9 @@ struct KernelCore::Impl { std::string name = "Suspend Thread Id:" + std::to_string(i); std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); - const auto type = - static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_SUSPEND); - auto thread_res = - Thread::Create(system, type, std::move(name), 0, 0, 0, static_cast<u32>(i), 0, - nullptr, std::move(init_func), init_func_parameter); + auto thread_res = KThread::Create(system, ThreadType::HighPriority, std::move(name), 0, + 0, 0, static_cast<u32>(i), 0, nullptr, + std::move(init_func), init_func_parameter); suspend_threads[i] = std::move(thread_res).Unwrap(); } @@ -207,6 +207,17 @@ struct KernelCore::Impl { return host_thread_id; } + // Gets the dummy KThread for the caller, allocating a new one if this is the first time + KThread* GetHostDummyThread() { + const thread_local auto thread = + KThread::Create( + system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, + KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr, + []([[maybe_unused]] void* arg) { UNREACHABLE(); }, nullptr) + .Unwrap(); + return thread.get(); + } + /// Registers a CPU core thread by allocating a host thread ID for it void RegisterCoreThread(std::size_t core_id) { ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); @@ -219,6 +230,7 @@ struct KernelCore::Impl { /// Registers a new host thread by allocating a host thread ID for it void RegisterHostThread() { [[maybe_unused]] const auto this_id = GetHostThreadId(); + [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(); } [[nodiscard]] u32 GetCurrentHostThreadID() { @@ -229,20 +241,21 @@ struct KernelCore::Impl { return this_id; } - [[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() { - Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); - result.host_handle = GetCurrentHostThreadID(); - if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { - return result; - } - const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); - const Kernel::Thread* current = sched.GetCurrentThread(); - if (current != nullptr && !current->IsPhantomMode()) { - result.guest_handle = current->GetGlobalHandle(); - } else { - result.guest_handle = InvalidHandle; + bool IsPhantomModeForSingleCore() const { + return is_phantom_mode_for_singlecore; + } + + void SetIsPhantomModeForSingleCore(bool value) { + ASSERT(!is_multicore); + is_phantom_mode_for_singlecore = value; + } + + KThread* GetCurrentEmuThread() { + const auto thread_id = GetCurrentHostThreadID(); + if (thread_id >= Core::Hardware::NUM_CPU_CORES) { + return GetHostDummyThread(); } - return result; + return schedulers[thread_id]->GetCurrentThread(); } void InitializeMemoryLayout() { @@ -307,7 +320,7 @@ struct KernelCore::Impl { std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; Kernel::TimeManager time_manager; - std::shared_ptr<ResourceLimit> system_resource_limit; + std::shared_ptr<KResourceLimit> system_resource_limit; std::shared_ptr<Core::Timing::EventType> preemption_event; @@ -342,11 +355,12 @@ struct KernelCore::Impl { // the release of itself std::unique_ptr<Common::ThreadWorker> service_thread_manager; - std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; + std::array<std::shared_ptr<KThread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; bool is_multicore{}; + bool is_phantom_mode_for_singlecore{}; u32 single_core_thread_id{}; std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{}; @@ -376,12 +390,12 @@ void KernelCore::Shutdown() { impl->Shutdown(); } -std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const { +std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const { return impl->system_resource_limit; } -std::shared_ptr<Thread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { - return impl->global_handle_table.Get<Thread>(handle); +std::shared_ptr<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { + return impl->global_handle_table.Get<KThread>(handle); } void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { @@ -546,8 +560,8 @@ u32 KernelCore::GetCurrentHostThreadID() const { return impl->GetCurrentHostThreadID(); } -Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const { - return impl->GetCurrentEmuThreadID(); +KThread* KernelCore::GetCurrentEmuThread() const { + return impl->GetCurrentEmuThread(); } Memory::MemoryManager& KernelCore::MemoryManager() { @@ -645,4 +659,12 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi }); } +bool KernelCore::IsPhantomModeForSingleCore() const { + return impl->IsPhantomModeForSingleCore(); +} + +void KernelCore::SetIsPhantomModeForSingleCore(bool value) { + impl->SetIsPhantomModeForSingleCore(value); +} + } // namespace Kernel |