core: hle: kernel: Ensure idle threads are closed before destroying scheduler.
This commit is contained in:
parent
68eee94875
commit
2b9560428b
3 changed files with 22 additions and 24 deletions
|
@ -617,13 +617,17 @@ KScheduler::KScheduler(Core::System& system_, s32 core_id_) : system{system_}, c
|
||||||
state.highest_priority_thread = nullptr;
|
state.highest_priority_thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KScheduler::~KScheduler() {
|
void KScheduler::Finalize() {
|
||||||
if (idle_thread) {
|
if (idle_thread) {
|
||||||
idle_thread->Close();
|
idle_thread->Close();
|
||||||
idle_thread = nullptr;
|
idle_thread = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KScheduler::~KScheduler() {
|
||||||
|
ASSERT(!idle_thread);
|
||||||
|
}
|
||||||
|
|
||||||
KThread* KScheduler::GetCurrentThread() const {
|
KThread* KScheduler::GetCurrentThread() const {
|
||||||
if (auto result = current_thread.load(); result) {
|
if (auto result = current_thread.load(); result) {
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -33,6 +33,8 @@ public:
|
||||||
explicit KScheduler(Core::System& system_, s32 core_id_);
|
explicit KScheduler(Core::System& system_, s32 core_id_);
|
||||||
~KScheduler();
|
~KScheduler();
|
||||||
|
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
/// Reschedules to the next available thread (call after current thread is suspended)
|
/// Reschedules to the next available thread (call after current thread is suspended)
|
||||||
void RescheduleCurrentCore();
|
void RescheduleCurrentCore();
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,9 @@ struct KernelCore::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeCores() {
|
void InitializeCores() {
|
||||||
for (auto& core : cores) {
|
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
|
||||||
core.Initialize(current_process->Is64BitProcess());
|
cores[core_id].Initialize(current_process->Is64BitProcess());
|
||||||
|
system.Memory().SetCurrentPageTable(*current_process, core_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,15 +132,6 @@ struct KernelCore::Impl {
|
||||||
next_user_process_id = KProcess::ProcessIDMin;
|
next_user_process_id = KProcess::ProcessIDMin;
|
||||||
next_thread_id = 1;
|
next_thread_id = 1;
|
||||||
|
|
||||||
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
|
|
||||||
if (suspend_threads[core_id]) {
|
|
||||||
suspend_threads[core_id]->Close();
|
|
||||||
suspend_threads[core_id] = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
schedulers[core_id].reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
cores.clear();
|
cores.clear();
|
||||||
|
|
||||||
global_handle_table->Finalize();
|
global_handle_table->Finalize();
|
||||||
|
@ -167,6 +159,16 @@ struct KernelCore::Impl {
|
||||||
CleanupObject(time_shared_mem);
|
CleanupObject(time_shared_mem);
|
||||||
CleanupObject(system_resource_limit);
|
CleanupObject(system_resource_limit);
|
||||||
|
|
||||||
|
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
|
||||||
|
if (suspend_threads[core_id]) {
|
||||||
|
suspend_threads[core_id]->Close();
|
||||||
|
suspend_threads[core_id] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
schedulers[core_id]->Finalize();
|
||||||
|
schedulers[core_id].reset();
|
||||||
|
}
|
||||||
|
|
||||||
// Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
|
// Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
|
||||||
next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
|
next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
|
||||||
|
|
||||||
|
@ -257,14 +259,6 @@ struct KernelCore::Impl {
|
||||||
|
|
||||||
void MakeCurrentProcess(KProcess* process) {
|
void MakeCurrentProcess(KProcess* process) {
|
||||||
current_process = process;
|
current_process = process;
|
||||||
if (process == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u32 core_id = GetCurrentHostThreadID();
|
|
||||||
if (core_id < Core::Hardware::NUM_CPU_CORES) {
|
|
||||||
system.Memory().SetCurrentPageTable(*process, core_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new host thread ID, should only be called by GetHostThreadId
|
/// Creates a new host thread ID, should only be called by GetHostThreadId
|
||||||
|
@ -1048,13 +1042,11 @@ void KernelCore::ExceptionalExit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::EnterSVCProfile() {
|
void KernelCore::EnterSVCProfile() {
|
||||||
std::size_t core = impl->GetCurrentHostThreadID();
|
impl->svc_ticks[CurrentPhysicalCoreIndex()] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
|
||||||
impl->svc_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::ExitSVCProfile() {
|
void KernelCore::ExitSVCProfile() {
|
||||||
std::size_t core = impl->GetCurrentHostThreadID();
|
MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
|
||||||
MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
|
std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
|
||||||
|
|
Loading…
Reference in a new issue