kern: SvcReturnFromException

This commit is contained in:
Michael Scire 2020-07-31 05:52:59 -07:00 committed by SciresM
parent 8cd81b3092
commit 5d462c626c
11 changed files with 647 additions and 56 deletions

View file

@ -704,7 +704,47 @@ namespace ams::kern {
}
bool KProcess::EnterUserException() {
MESOSPHERE_UNIMPLEMENTED();
/* Get the current thread. */
KThread *cur_thread = GetCurrentThreadPointer();
MESOSPHERE_ASSERT(this == cur_thread->GetOwnerProcess());
/* Try to claim the exception thread. */
if (this->exception_thread != cur_thread) {
const uintptr_t address_key = reinterpret_cast<uintptr_t>(std::addressof(this->exception_thread));
while (true) {
{
KScopedSchedulerLock sl;
/* If the thread is terminating, it can't enter. */
if (cur_thread->IsTerminationRequested()) {
return false;
}
/* If we have no exception thread, we succeeded. */
if (this->exception_thread == nullptr) {
this->exception_thread = cur_thread;
return true;
}
/* Otherwise, wait for us to not have an exception thread. */
cur_thread->SetAddressKey(address_key);
this->exception_thread->AddWaiter(cur_thread);
if (cur_thread->GetState() == KThread::ThreadState_Runnable) {
cur_thread->SetState(KThread::ThreadState_Waiting);
}
}
/* Remove the thread as a waiter from the lock owner. */
{
KScopedSchedulerLock sl;
KThread *owner_thread = cur_thread->GetLockOwner();
if (owner_thread != nullptr) {
owner_thread->RemoveWaiter(cur_thread);
}
}
}
} else {
return false;
}
}
bool KProcess::LeaveUserException() {
@ -715,8 +755,18 @@ namespace ams::kern {
KScopedSchedulerLock sl;
if (this->exception_thread == thread) {
/* TODO */
MESOSPHERE_UNIMPLEMENTED();
this->exception_thread = nullptr;
/* Remove waiter thread. */
s32 num_waiters;
KThread *next = thread->RemoveWaiterByKey(std::addressof(num_waiters), reinterpret_cast<uintptr_t>(std::addressof(this->exception_thread)));
if (next != nullptr) {
if (next->GetState() == KThread::ThreadState_Waiting) {
next->SetState(KThread::ThreadState_Runnable);
}
}
return true;
} else {
return false;
}