mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
kern: update process/thread for new running/termination semantics
This commit is contained in:
parent
ec1d9c4c49
commit
256eb92f4c
8 changed files with 76 additions and 82 deletions
|
@ -77,8 +77,7 @@ namespace ams::kern {
|
||||||
bool m_is_initialized{};
|
bool m_is_initialized{};
|
||||||
bool m_is_application{};
|
bool m_is_application{};
|
||||||
char m_name[13]{};
|
char m_name[13]{};
|
||||||
std::atomic<u16> m_num_threads{};
|
std::atomic<u16> m_num_running_threads{};
|
||||||
u16 m_peak_num_threads{};
|
|
||||||
u32 m_flags{};
|
u32 m_flags{};
|
||||||
KMemoryManager::Pool m_memory_pool{};
|
KMemoryManager::Pool m_memory_pool{};
|
||||||
s64 m_schedule_count{};
|
s64 m_schedule_count{};
|
||||||
|
@ -108,7 +107,6 @@ namespace ams::kern {
|
||||||
KThread *m_running_threads[cpu::NumCores]{};
|
KThread *m_running_threads[cpu::NumCores]{};
|
||||||
u64 m_running_thread_idle_counts[cpu::NumCores]{};
|
u64 m_running_thread_idle_counts[cpu::NumCores]{};
|
||||||
KThread *m_pinned_threads[cpu::NumCores]{};
|
KThread *m_pinned_threads[cpu::NumCores]{};
|
||||||
std::atomic<s32> m_num_created_threads{};
|
|
||||||
std::atomic<s64> m_cpu_time{};
|
std::atomic<s64> m_cpu_time{};
|
||||||
std::atomic<s64> m_num_process_switches{};
|
std::atomic<s64> m_num_process_switches{};
|
||||||
std::atomic<s64> m_num_thread_switches{};
|
std::atomic<s64> m_num_thread_switches{};
|
||||||
|
@ -124,7 +122,7 @@ namespace ams::kern {
|
||||||
private:
|
private:
|
||||||
Result Initialize(const ams::svc::CreateProcessParameter ¶ms);
|
Result Initialize(const ams::svc::CreateProcessParameter ¶ms);
|
||||||
|
|
||||||
void StartTermination();
|
Result StartTermination();
|
||||||
void FinishTermination();
|
void FinishTermination();
|
||||||
|
|
||||||
void PinThread(s32 core_id, KThread *thread) {
|
void PinThread(s32 core_id, KThread *thread) {
|
||||||
|
@ -285,8 +283,8 @@ namespace ams::kern {
|
||||||
constexpr s64 GetScheduledCount() const { return m_schedule_count; }
|
constexpr s64 GetScheduledCount() const { return m_schedule_count; }
|
||||||
void IncrementScheduledCount() { ++m_schedule_count; }
|
void IncrementScheduledCount() { ++m_schedule_count; }
|
||||||
|
|
||||||
void IncrementThreadCount();
|
void IncrementRunningThreadCount();
|
||||||
void DecrementThreadCount();
|
void DecrementRunningThreadCount();
|
||||||
|
|
||||||
size_t GetTotalSystemResourceSize() const { return m_system_resource_num_pages * PageSize; }
|
size_t GetTotalSystemResourceSize() const { return m_system_resource_num_pages * PageSize; }
|
||||||
size_t GetUsedSystemResourceSize() const {
|
size_t GetUsedSystemResourceSize() const {
|
||||||
|
|
|
@ -340,7 +340,7 @@ namespace ams::kern {
|
||||||
return this->GetDpc() != 0;
|
return this->GetDpc() != 0;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void Suspend();
|
void UpdateState();
|
||||||
ALWAYS_INLINE void AddWaiterImpl(KThread *thread);
|
ALWAYS_INLINE void AddWaiterImpl(KThread *thread);
|
||||||
ALWAYS_INLINE void RemoveWaiterImpl(KThread *thread);
|
ALWAYS_INLINE void RemoveWaiterImpl(KThread *thread);
|
||||||
ALWAYS_INLINE static void RestorePriority(KThread *thread);
|
ALWAYS_INLINE static void RestorePriority(KThread *thread);
|
||||||
|
@ -535,7 +535,7 @@ namespace ams::kern {
|
||||||
Result Run();
|
Result Run();
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
void Terminate();
|
Result Terminate();
|
||||||
ThreadState RequestTerminate();
|
ThreadState RequestTerminate();
|
||||||
|
|
||||||
Result Sleep(s64 timeout);
|
Result Sleep(s64 timeout);
|
||||||
|
|
|
@ -526,7 +526,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
#if defined(MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT)
|
#if defined(MESOSPHERE_ENABLE_MEMORY_CONTROLLER_INTERRUPT)
|
||||||
{
|
{
|
||||||
/* Clear the interrupt when we're done. */
|
/* Clear the interrupt when we're done. */
|
||||||
ON_SCOPE_EXIT { Kernel::GetInterruptManager().ClearInterrupt(KInterruptName_MemoryController); };
|
ON_SCOPE_EXIT { Kernel::GetInterruptManager().ClearInterrupt(KInterruptName_MemoryController, GetCurrentCoreId()); };
|
||||||
|
|
||||||
/* Get and clear the interrupt status. */
|
/* Get and clear the interrupt status. */
|
||||||
u32 int_status, err_status, err_adr;
|
u32 int_status, err_status, err_adr;
|
||||||
|
|
|
@ -210,6 +210,7 @@ namespace ams::kern {
|
||||||
/* Run the processes. */
|
/* Run the processes. */
|
||||||
for (size_t i = 0; i < g_initial_process_binary_header.num_processes; i++) {
|
for (size_t i = 0; i < g_initial_process_binary_header.num_processes; i++) {
|
||||||
MESOSPHERE_R_ABORT_UNLESS(infos[i].process->Run(infos[i].priority, infos[i].stack_size));
|
MESOSPHERE_R_ABORT_UNLESS(infos[i].process->Run(infos[i].priority, infos[i].stack_size));
|
||||||
|
infos[i].process->Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace ams::kern {
|
||||||
std::atomic<u64> g_initial_process_id = InitialProcessIdMin;
|
std::atomic<u64> g_initial_process_id = InitialProcessIdMin;
|
||||||
std::atomic<u64> g_process_id = ProcessIdMin;
|
std::atomic<u64> g_process_id = ProcessIdMin;
|
||||||
|
|
||||||
void TerminateChildren(KProcess *process, const KThread *thread_to_not_terminate) {
|
Result TerminateChildren(KProcess *process, const KThread *thread_to_not_terminate) {
|
||||||
/* Request that all children threads terminate. */
|
/* Request that all children threads terminate. */
|
||||||
{
|
{
|
||||||
KScopedLightLock proc_lk(process->GetListLock());
|
KScopedLightLock proc_lk(process->GetListLock());
|
||||||
|
@ -70,9 +70,14 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate and close the thread. */
|
/* Terminate and close the thread. */
|
||||||
cur_child->Terminate();
|
ON_SCOPE_EXIT { cur_child->Close(); };
|
||||||
cur_child->Close();
|
|
||||||
|
if (Result terminate_result = cur_child->Terminate(); svc::ResultTerminationRequested::Includes(terminate_result)) {
|
||||||
|
return terminate_result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -206,9 +211,7 @@ namespace ams::kern {
|
||||||
KSystemControl::GenerateRandomBytes(m_entropy, sizeof(m_entropy));
|
KSystemControl::GenerateRandomBytes(m_entropy, sizeof(m_entropy));
|
||||||
|
|
||||||
/* Clear remaining fields. */
|
/* Clear remaining fields. */
|
||||||
m_num_threads = 0;
|
m_num_running_threads = 0;
|
||||||
m_peak_num_threads = 0;
|
|
||||||
m_num_created_threads = 0;
|
|
||||||
m_num_process_switches = 0;
|
m_num_process_switches = 0;
|
||||||
m_num_thread_switches = 0;
|
m_num_thread_switches = 0;
|
||||||
m_num_fpu_switches = 0;
|
m_num_fpu_switches = 0;
|
||||||
|
@ -402,12 +405,14 @@ namespace ams::kern {
|
||||||
this->FinishTermination();
|
this->FinishTermination();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::StartTermination() {
|
Result KProcess::StartTermination() {
|
||||||
/* Terminate child threads other than the current one. */
|
/* Finalize the handle table, when we're done. */
|
||||||
TerminateChildren(this, GetCurrentThreadPointer());
|
ON_SCOPE_EXIT {
|
||||||
|
m_handle_table.Finalize();
|
||||||
|
};
|
||||||
|
|
||||||
/* Finalize the handle tahble. */
|
/* Terminate child threads other than the current one. */
|
||||||
m_handle_table.Finalize();
|
return TerminateChildren(this, GetCurrentThreadPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::FinishTermination() {
|
void KProcess::FinishTermination() {
|
||||||
|
@ -485,16 +490,22 @@ namespace ams::kern {
|
||||||
/* If we need to terminate, do so. */
|
/* If we need to terminate, do so. */
|
||||||
if (needs_terminate) {
|
if (needs_terminate) {
|
||||||
/* Start termination. */
|
/* Start termination. */
|
||||||
this->StartTermination();
|
if (R_SUCCEEDED(this->StartTermination())) {
|
||||||
|
/* Note for debug that we're terminating the process. */
|
||||||
|
MESOSPHERE_LOG("KProcess::Terminate() OK pid=%ld name=%-12s\n", m_process_id, m_name);
|
||||||
|
|
||||||
/* Note for debug that we're terminating the process. */
|
/* Call the debug callback. */
|
||||||
MESOSPHERE_LOG("KProcess::Terminate() pid=%ld name=%-12s\n", m_process_id, m_name);
|
KDebug::OnTerminateProcess(this);
|
||||||
|
|
||||||
/* Call the debug callback. */
|
/* Finish termination. */
|
||||||
KDebug::OnTerminateProcess(this);
|
this->FinishTermination();
|
||||||
|
} else {
|
||||||
|
/* Note for debug that we're terminating the process. */
|
||||||
|
MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name);
|
||||||
|
|
||||||
/* Finish termination. */
|
/* Register the process as a work task. */
|
||||||
this->FinishTermination();
|
KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -703,19 +714,16 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::IncrementThreadCount() {
|
void KProcess::IncrementRunningThreadCount() {
|
||||||
MESOSPHERE_ASSERT(m_num_threads >= 0);
|
MESOSPHERE_ASSERT(m_num_running_threads.load() >= 0);
|
||||||
++m_num_created_threads;
|
|
||||||
|
|
||||||
if (const auto count = ++m_num_threads; count > m_peak_num_threads) {
|
m_num_running_threads.fetch_add(1);
|
||||||
m_peak_num_threads = count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::DecrementThreadCount() {
|
void KProcess::DecrementRunningThreadCount() {
|
||||||
MESOSPHERE_ASSERT(m_num_threads > 0);
|
MESOSPHERE_ASSERT(m_num_running_threads.load() > 0);
|
||||||
|
|
||||||
if (const auto count = --m_num_threads; count == 0) {
|
if (m_num_running_threads.fetch_sub(1) == 1) {
|
||||||
this->Terminate();
|
this->Terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,7 +904,7 @@ namespace ams::kern {
|
||||||
/* Create a new thread for the process. */
|
/* Create a new thread for the process. */
|
||||||
KThread *main_thread = KThread::Create();
|
KThread *main_thread = KThread::Create();
|
||||||
R_UNLESS(main_thread != nullptr, svc::ResultOutOfResource());
|
R_UNLESS(main_thread != nullptr, svc::ResultOutOfResource());
|
||||||
auto thread_guard = SCOPE_GUARD { main_thread->Close(); };
|
ON_SCOPE_EXIT { main_thread->Close(); };
|
||||||
|
|
||||||
/* Initialize the thread. */
|
/* Initialize the thread. */
|
||||||
R_TRY(KThread::InitializeUserThread(main_thread, reinterpret_cast<KThreadFunction>(GetVoidPointer(this->GetEntryPoint())), 0, stack_top, priority, m_ideal_core_id, this));
|
R_TRY(KThread::InitializeUserThread(main_thread, reinterpret_cast<KThreadFunction>(GetVoidPointer(this->GetEntryPoint())), 0, stack_top, priority, m_ideal_core_id, this));
|
||||||
|
@ -919,9 +927,11 @@ namespace ams::kern {
|
||||||
/* Run our thread. */
|
/* Run our thread. */
|
||||||
R_TRY(main_thread->Run());
|
R_TRY(main_thread->Run());
|
||||||
|
|
||||||
|
/* Open a reference to represent that we're running. */
|
||||||
|
this->Open();
|
||||||
|
|
||||||
/* We succeeded! Cancel our guards. */
|
/* We succeeded! Cancel our guards. */
|
||||||
state_guard.Cancel();
|
state_guard.Cancel();
|
||||||
thread_guard.Cancel();
|
|
||||||
ht_guard.Cancel();
|
ht_guard.Cancel();
|
||||||
stack_guard.Cancel();
|
stack_guard.Cancel();
|
||||||
mem_reservation.Commit();
|
mem_reservation.Commit();
|
||||||
|
|
|
@ -184,7 +184,6 @@ namespace ams::kern {
|
||||||
if (owner != nullptr) {
|
if (owner != nullptr) {
|
||||||
m_parent = owner;
|
m_parent = owner;
|
||||||
m_parent->Open();
|
m_parent->Open();
|
||||||
m_parent->IncrementThreadCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize thread context. */
|
/* Initialize thread context. */
|
||||||
|
@ -312,11 +311,6 @@ namespace ams::kern {
|
||||||
CleanupKernelStack(reinterpret_cast<uintptr_t>(m_kernel_stack_top));
|
CleanupKernelStack(reinterpret_cast<uintptr_t>(m_kernel_stack_top));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrement the parent process's thread count. */
|
|
||||||
if (m_parent != nullptr) {
|
|
||||||
m_parent->DecrementThreadCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform inherited finalization. */
|
/* Perform inherited finalization. */
|
||||||
KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>::Finalize();
|
KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>::Finalize();
|
||||||
}
|
}
|
||||||
|
@ -444,11 +438,7 @@ namespace ams::kern {
|
||||||
m_suspend_allowed_flags &= ~(1 << (SuspendType_Thread + ThreadState_SuspendShift));
|
m_suspend_allowed_flags &= ~(1 << (SuspendType_Thread + ThreadState_SuspendShift));
|
||||||
|
|
||||||
/* Update our state. */
|
/* Update our state. */
|
||||||
const ThreadState old_state = m_thread_state;
|
this->UpdateState();
|
||||||
m_thread_state = static_cast<ThreadState>(this->GetSuspendFlags() | (old_state & ThreadState_Mask));
|
|
||||||
if (m_thread_state != old_state) {
|
|
||||||
KScheduler::OnThreadStateChanged(this, old_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update our SVC access permissions. */
|
/* Update our SVC access permissions. */
|
||||||
|
@ -499,11 +489,7 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update our state. */
|
/* Update our state. */
|
||||||
const ThreadState old_state = m_thread_state;
|
this->UpdateState();
|
||||||
m_thread_state = static_cast<ThreadState>(this->GetSuspendFlags() | (old_state & ThreadState_Mask));
|
|
||||||
if (m_thread_state != old_state) {
|
|
||||||
KScheduler::OnThreadStateChanged(this, old_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update our SVC access permissions. */
|
/* Update our SVC access permissions. */
|
||||||
|
@ -790,11 +776,7 @@ namespace ams::kern {
|
||||||
m_suspend_request_flags &= ~(1u << (ThreadState_SuspendShift + type));
|
m_suspend_request_flags &= ~(1u << (ThreadState_SuspendShift + type));
|
||||||
|
|
||||||
/* Update our state. */
|
/* Update our state. */
|
||||||
const ThreadState old_state = m_thread_state;
|
this->UpdateState();
|
||||||
m_thread_state = static_cast<ThreadState>(this->GetSuspendFlags() | (old_state & ThreadState_Mask));
|
|
||||||
if (m_thread_state != old_state) {
|
|
||||||
KScheduler::OnThreadStateChanged(this, old_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::WaitCancel() {
|
void KThread::WaitCancel() {
|
||||||
|
@ -830,20 +812,22 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ABORT_UNLESS(this->GetNumKernelWaiters() == 0);
|
MESOSPHERE_ABORT_UNLESS(this->GetNumKernelWaiters() == 0);
|
||||||
|
|
||||||
/* Perform the suspend. */
|
/* Perform the suspend. */
|
||||||
this->Suspend();
|
this->UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::Suspend() {
|
void KThread::UpdateState() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
||||||
MESOSPHERE_ASSERT(this->IsSuspendRequested());
|
|
||||||
|
|
||||||
/* Set our suspend flags in state. */
|
/* Set our suspend flags in state. */
|
||||||
const auto old_state = m_thread_state;
|
const auto old_state = m_thread_state;
|
||||||
m_thread_state = static_cast<ThreadState>(this->GetSuspendFlags() | (old_state & ThreadState_Mask));
|
const auto new_state = static_cast<ThreadState>(this->GetSuspendFlags() | (old_state & ThreadState_Mask));
|
||||||
|
m_thread_state = new_state;
|
||||||
|
|
||||||
/* Note the state change in scheduler. */
|
/* Note the state change in scheduler. */
|
||||||
KScheduler::OnThreadStateChanged(this, old_state);
|
if (new_state != old_state) {
|
||||||
|
KScheduler::OnThreadStateChanged(this, old_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::Continue() {
|
void KThread::Continue() {
|
||||||
|
@ -1137,15 +1121,21 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* If the current thread has been asked to suspend, suspend it and retry. */
|
/* If the current thread has been asked to suspend, suspend it and retry. */
|
||||||
if (GetCurrentThread().IsSuspended()) {
|
if (GetCurrentThread().IsSuspended()) {
|
||||||
GetCurrentThread().Suspend();
|
GetCurrentThread().UpdateState();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're not a kernel thread and we've been asked to suspend, suspend ourselves. */
|
/* If we're not a kernel thread and we've been asked to suspend, suspend ourselves. */
|
||||||
if (this->IsUserThread() && this->IsSuspended()) {
|
if (KProcess *parent = this->GetOwnerProcess(); parent != nullptr) {
|
||||||
this->Suspend();
|
if (this->IsSuspended()) {
|
||||||
|
this->UpdateState();
|
||||||
|
}
|
||||||
|
parent->IncrementRunningThreadCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Open a reference, now that we're running. */
|
||||||
|
this->Open();
|
||||||
|
|
||||||
/* Set our state and finish. */
|
/* Set our state and finish. */
|
||||||
this->SetState(KThread::ThreadState_Runnable);
|
this->SetState(KThread::ThreadState_Runnable);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -1160,10 +1150,11 @@ namespace ams::kern {
|
||||||
/* Call the debug callback. */
|
/* Call the debug callback. */
|
||||||
KDebug::OnExitThread(this);
|
KDebug::OnExitThread(this);
|
||||||
|
|
||||||
/* Release the thread resource hint from parent. */
|
/* Release the thread resource hint, running thread count from parent. */
|
||||||
if (m_parent != nullptr) {
|
if (m_parent != nullptr) {
|
||||||
m_parent->ReleaseResource(ams::svc::LimitableResource_ThreadCountMax, 0, 1);
|
m_parent->ReleaseResource(ams::svc::LimitableResource_ThreadCountMax, 0, 1);
|
||||||
m_resource_limit_release_hint = true;
|
m_resource_limit_release_hint = true;
|
||||||
|
m_parent->DecrementRunningThreadCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform termination. */
|
/* Perform termination. */
|
||||||
|
@ -1172,6 +1163,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Disallow all suspension. */
|
/* Disallow all suspension. */
|
||||||
m_suspend_allowed_flags = 0;
|
m_suspend_allowed_flags = 0;
|
||||||
|
this->UpdateState();
|
||||||
|
|
||||||
/* Start termination. */
|
/* Start termination. */
|
||||||
this->StartTermination();
|
this->StartTermination();
|
||||||
|
@ -1183,7 +1175,7 @@ namespace ams::kern {
|
||||||
MESOSPHERE_PANIC("KThread::Exit() would return");
|
MESOSPHERE_PANIC("KThread::Exit() would return");
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::Terminate() {
|
Result KThread::Terminate() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
MESOSPHERE_ASSERT(this != GetCurrentThreadPointer());
|
MESOSPHERE_ASSERT(this != GetCurrentThreadPointer());
|
||||||
|
|
||||||
|
@ -1192,7 +1184,9 @@ namespace ams::kern {
|
||||||
/* If the thread isn't terminated, wait for it to terminate. */
|
/* If the thread isn't terminated, wait for it to terminate. */
|
||||||
s32 index;
|
s32 index;
|
||||||
KSynchronizationObject *objects[] = { this };
|
KSynchronizationObject *objects[] = { this };
|
||||||
KSynchronizationObject::Wait(std::addressof(index), objects, 1, ams::svc::WaitInfinite);
|
return KSynchronizationObject::Wait(std::addressof(index), objects, 1, ams::svc::WaitInfinite);
|
||||||
|
} else {
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,7 +1217,7 @@ namespace ams::kern {
|
||||||
/* If the thread is suspended, continue it. */
|
/* If the thread is suspended, continue it. */
|
||||||
if (this->IsSuspended()) {
|
if (this->IsSuspended()) {
|
||||||
m_suspend_allowed_flags = 0;
|
m_suspend_allowed_flags = 0;
|
||||||
this->Continue();
|
this->UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change the thread's priority to be higher than any system thread's. */
|
/* Change the thread's priority to be higher than any system thread's. */
|
||||||
|
|
|
@ -286,12 +286,7 @@ namespace ams::kern::svc {
|
||||||
process->SetIdealCoreId(core_id);
|
process->SetIdealCoreId(core_id);
|
||||||
|
|
||||||
/* Run the process. */
|
/* Run the process. */
|
||||||
R_TRY(process->Run(priority, static_cast<size_t>(main_thread_stack_size)));
|
return process->Run(priority, static_cast<size_t>(main_thread_stack_size));
|
||||||
|
|
||||||
/* Open a reference to the process, since it's now running. */
|
|
||||||
process->Open();
|
|
||||||
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TerminateProcess(ams::svc::Handle process_handle) {
|
Result TerminateProcess(ams::svc::Handle process_handle) {
|
||||||
|
|
|
@ -75,11 +75,7 @@ namespace ams::kern::svc {
|
||||||
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidHandle());
|
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidHandle());
|
||||||
|
|
||||||
/* Try to start the thread. */
|
/* Try to start the thread. */
|
||||||
R_TRY(thread->Run());
|
return thread->Run();
|
||||||
|
|
||||||
/* If we succeeded, persist a reference to the thread. */
|
|
||||||
thread->Open();
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExitThread() {
|
void ExitThread() {
|
||||||
|
|
Loading…
Reference in a new issue