kern: implement unsuspension of init threads

This commit is contained in:
Michael Scire 2020-02-19 20:42:21 -08:00
parent c568788609
commit aae3c789f2
10 changed files with 117 additions and 17 deletions

View file

@ -39,14 +39,6 @@ namespace ams::kern::arch::arm64 {
}
}
void KSupervisorPageTable::Activate() {
/* Initialize, using process id = 0xFFFFFFFF */
this->page_table.Initialize(0xFFFFFFFF);
/* Invalidate entire TLB. */
cpu::InvalidateEntireTlb();
}
void KSupervisorPageTable::Finalize(s32 core_id) {
MESOSPHERE_TODO_IMPLEMENT();
}

View file

@ -222,6 +222,34 @@ namespace ams::kern {
return static_cast<u8 *>(tlp->GetPointer()) + (GetInteger(addr) & (PageSize - 1));
}
bool KProcess::ReserveResource(ams::svc::LimitableResource which, s64 value) {
if (KResourceLimit *rl = this->GetResourceLimit(); rl != nullptr) {
return rl->Reserve(which, value);
} else {
return true;
}
}
bool KProcess::ReserveResource(ams::svc::LimitableResource which, s64 value, s64 timeout) {
if (KResourceLimit *rl = this->GetResourceLimit(); rl != nullptr) {
return rl->Reserve(which, value, timeout);
} else {
return true;
}
}
void KProcess::ReleaseResource(ams::svc::LimitableResource which, s64 value) {
if (KResourceLimit *rl = this->GetResourceLimit(); rl != nullptr) {
rl->Release(which, value);
}
}
void KProcess::ReleaseResource(ams::svc::LimitableResource which, s64 value, s64 hint) {
if (KResourceLimit *rl = this->GetResourceLimit(); rl != nullptr) {
rl->Release(which, value, hint);
}
}
void KProcess::IncrementThreadCount() {
MESOSPHERE_ASSERT(this->num_threads >= 0);
++this->num_created_threads;
@ -335,6 +363,9 @@ namespace ams::kern {
stack_guard.Cancel();
mem_reservation.Commit();
/* Note for debug that we're running a new process. */
MESOSPHERE_LOG("KProcess::Run() pid=%ld name=%-12s thread=%ld affinity=0x%lx ideal_core=%d active_core=%d\n", this->process_id, this->name, main_thread->GetId(), main_thread->GetAffinityMask().GetAffinityMask(), main_thread->GetIdealCore(), main_thread->GetActiveCore());
return ResultSuccess();
}

View file

@ -38,7 +38,7 @@ namespace ams::kern {
ALWAYS_INLINE void IncrementScheduledCount(KThread *thread) {
if (KProcess *parent = thread->GetOwnerProcess(); parent != nullptr) {
MESOSPHERE_TODO("parent->IncrementScheduledCount();");
parent->IncrementScheduledCount();
}
}
@ -234,7 +234,7 @@ namespace ams::kern {
const s64 tick_diff = cur_tick - prev_tick;
cur_thread->AddCpuTime(tick_diff);
if (cur_process != nullptr) {
MESOSPHERE_TODO("cur_process->AddCpuTime(tick_diff);");
cur_process->AddCpuTime(tick_diff);
}
this->last_context_switch_time = cur_tick;
@ -252,7 +252,7 @@ namespace ams::kern {
/* Switch the current process, if we're switching processes. */
if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) {
MESOSPHERE_TODO("KProcess::Switch");
KProcess::Switch(cur_process, next_process);
}
/* Set the new thread. */

View file

@ -232,12 +232,23 @@ namespace ams::kern {
void KThread::PostDestroy(uintptr_t arg) {
KProcess *owner = reinterpret_cast<KProcess *>(arg & ~1ul);
const bool resource_limit_release_hint = (arg & 1);
const s64 hint_value = (resource_limit_release_hint ? 0 : 1);
if (owner != nullptr) {
MESOSPHERE_TODO("Release from owner resource limit.");
(void)(resource_limit_release_hint);
owner->ReleaseResource(ams::svc::LimitableResource_ThreadCountMax, 1, hint_value);
owner->Close();
} else {
MESOSPHERE_TODO("Release from system resource limit.");
Kernel::GetSystemResourceLimit().Release(ams::svc::LimitableResource_ThreadCountMax, 1, hint_value);
}
}
void KThread::ResumeThreadsSuspendedForInit() {
KThread::ListAccessor list_accessor;
{
KScopedSchedulerLock sl;
for (auto &thread : list_accessor) {
static_cast<KThread &>(thread).Resume(SuspendType_Init);
}
}
}
@ -310,6 +321,8 @@ namespace ams::kern {
Result KThread::SetPriorityToIdle() {
MESOSPHERE_ASSERT_THIS();
KScopedSchedulerLock sl;
/* Change both our priorities to the idle thread priority. */
const s32 old_priority = this->priority;
this->priority = IdleThreadPriority;
@ -325,12 +338,28 @@ namespace ams::kern {
KScopedSchedulerLock lk;
/* Note the request in our flags. */
this->suspend_request_flags |= (1 << (ThreadState_SuspendShift + type));
this->suspend_request_flags |= (1u << (ThreadState_SuspendShift + type));
/* Try to perform the suspend. */
this->TrySuspend();
}
void KThread::Resume(SuspendType type) {
MESOSPHERE_ASSERT_THIS();
KScopedSchedulerLock sl;
/* Clear the request in our flags. */
this->suspend_request_flags &= ~(1u << (ThreadState_SuspendShift + type));
/* Update our state. */
const ThreadState old_state = this->thread_state;
this->thread_state = static_cast<ThreadState>(this->GetSuspendFlags() | (old_state & ThreadState_Mask));
if (this->thread_state != old_state) {
KScheduler::OnThreadStateChanged(this, old_state);
}
}
void KThread::TrySuspend() {
MESOSPHERE_ASSERT_THIS();
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());

View file

@ -122,7 +122,8 @@ namespace ams::kern {
/* We're done initializing! */
Kernel::SetState(Kernel::State::Initialized);
MESOSPHERE_TODO("KThread::ResumeThreadsSuspendedForInit();");
/* Resume all threads suspended while we initialized. */
KThread::ResumeThreadsSuspendedForInit();
}
cpu::SynchronizeAllCores();