mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-23 12:22:08 +00:00
kern SvcGetCurrentProcessorNumber, SvcSetProcessActivity, half of SvcSetThreadActivity
This commit is contained in:
parent
23eed522d3
commit
1d4d637818
6 changed files with 148 additions and 7 deletions
|
@ -158,6 +158,10 @@ namespace ams::kern {
|
|||
return this->is_suspended;
|
||||
}
|
||||
|
||||
constexpr void SetSuspended(bool suspended) {
|
||||
this->is_suspended = suspended;
|
||||
}
|
||||
|
||||
Result Terminate();
|
||||
|
||||
constexpr bool IsTerminated() const {
|
||||
|
@ -257,6 +261,8 @@ namespace ams::kern {
|
|||
|
||||
Result Reset();
|
||||
|
||||
Result SetActivity(ams::svc::ProcessActivity activity);
|
||||
|
||||
void SetPreemptionState();
|
||||
|
||||
Result SignalToAddress(KProcessAddress address) {
|
||||
|
|
|
@ -433,11 +433,14 @@ namespace ams::kern {
|
|||
|
||||
constexpr u32 GetSuspendFlags() const { return this->suspend_allowed_flags & this->suspend_request_flags; }
|
||||
constexpr bool IsSuspended() const { return this->GetSuspendFlags() != 0; }
|
||||
constexpr bool IsSuspendRequested(SuspendType type) const { return (this->suspend_request_flags & (1u << (ThreadState_SuspendShift + type))) != 0; }
|
||||
void RequestSuspend(SuspendType type);
|
||||
void Resume(SuspendType type);
|
||||
void TrySuspend();
|
||||
void Continue();
|
||||
|
||||
Result SetActivity(ams::svc::ThreadActivity activity);
|
||||
|
||||
void ContinueIfHasKernelWaiters() {
|
||||
if (this->GetNumKernelWaiters() > 0) {
|
||||
this->Continue();
|
||||
|
|
|
@ -879,6 +879,48 @@ namespace ams::kern {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KProcess::SetActivity(ams::svc::ProcessActivity activity) {
|
||||
/* Lock ourselves and the scheduler. */
|
||||
KScopedLightLock lk(this->state_lock);
|
||||
KScopedLightLock list_lk(this->list_lock);
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* Validate our state. */
|
||||
R_UNLESS(this->state != State_Terminating, svc::ResultInvalidState());
|
||||
R_UNLESS(this->state != State_Terminated, svc::ResultInvalidState());
|
||||
|
||||
/* Either pause or resume. */
|
||||
if (activity == ams::svc::ProcessActivity_Paused) {
|
||||
/* Verify that we're not suspended. */
|
||||
R_UNLESS(!this->is_suspended, svc::ResultInvalidState());
|
||||
|
||||
/* Suspend all threads. */
|
||||
auto end = this->GetThreadList().end();
|
||||
for (auto it = this->GetThreadList().begin(); it != end; ++it) {
|
||||
it->RequestSuspend(KThread::SuspendType_Process);
|
||||
}
|
||||
|
||||
/* Set ourselves as suspended. */
|
||||
this->SetSuspended(true);
|
||||
} else {
|
||||
MESOSPHERE_ASSERT(activity == ams::svc::ProcessActivity_Runnable);
|
||||
|
||||
/* Verify that we're suspended. */
|
||||
R_UNLESS(this->is_suspended, svc::ResultInvalidState());
|
||||
|
||||
/* Resume all threads. */
|
||||
auto end = this->GetThreadList().end();
|
||||
for (auto it = this->GetThreadList().begin(); it != end; ++it) {
|
||||
it->Resume(KThread::SuspendType_Process);
|
||||
}
|
||||
|
||||
/* Set ourselves as resumed. */
|
||||
this->SetSuspended(false);
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
KProcess::State KProcess::SetDebugObject(void *debug_object) {
|
||||
/* Attaching should only happen to non-null objects while the scheduler is locked. */
|
||||
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
||||
|
|
|
@ -450,6 +450,7 @@ namespace ams::kern {
|
|||
MESOSPHERE_ASSERT(this->parent != nullptr);
|
||||
MESOSPHERE_ASSERT(affinity_mask != 0);
|
||||
{
|
||||
KScopedLightLock lk(this->activity_pause_lock);
|
||||
KScopedSchedulerLock sl;
|
||||
MESOSPHERE_ASSERT(this->num_core_migration_disables >= 0);
|
||||
|
||||
|
@ -491,6 +492,8 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: Paused waiter list. */
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -610,6 +613,38 @@ namespace ams::kern {
|
|||
KScheduler::OnThreadStateChanged(this, old_state);
|
||||
}
|
||||
|
||||
Result KThread::SetActivity(ams::svc::ThreadActivity activity) {
|
||||
/* Lock ourselves and the scheduler. */
|
||||
KScopedLightLock lk(this->activity_pause_lock);
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
/* Verify our state. */
|
||||
const auto cur_state = this->GetState();
|
||||
R_UNLESS((cur_state == ThreadState_Waiting || cur_state == ThreadState_Runnable), svc::ResultInvalidState());
|
||||
|
||||
/* Either pause or resume. */
|
||||
if (activity == ams::svc::ThreadActivity_Paused) {
|
||||
/* Verify that we're not suspended. */
|
||||
R_UNLESS(!this->IsSuspendRequested(SuspendType_Thread), svc::ResultInvalidState());
|
||||
|
||||
/* Suspend. */
|
||||
this->RequestSuspend(SuspendType_Thread);
|
||||
|
||||
/* TODO: Paused waiter list. */
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
} else {
|
||||
MESOSPHERE_ASSERT(activity == ams::svc::ThreadActivity_Runnable);
|
||||
|
||||
/* Verify that we're suspended. */
|
||||
R_UNLESS(this->IsSuspendRequested(SuspendType_Thread), svc::ResultInvalidState());
|
||||
|
||||
/* Resume. */
|
||||
this->Resume(SuspendType_Thread);
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void KThread::AddWaiterImpl(KThread *thread) {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
||||
|
|
|
@ -21,28 +21,81 @@ namespace ams::kern::svc {
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr bool IsValidThreadActivity(ams::svc::ThreadActivity thread_activity) {
|
||||
switch (thread_activity) {
|
||||
case ams::svc::ThreadActivity_Runnable:
|
||||
case ams::svc::ThreadActivity_Paused:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool IsValidProcessActivity(ams::svc::ProcessActivity process_activity) {
|
||||
switch (process_activity) {
|
||||
case ams::svc::ProcessActivity_Runnable:
|
||||
case ams::svc::ProcessActivity_Paused:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Result SetThreadActivity(ams::svc::Handle thread_handle, ams::svc::ThreadActivity thread_activity) {
|
||||
/* Validate the activity. */
|
||||
R_UNLESS(IsValidThreadActivity(thread_activity), svc::ResultInvalidEnumValue());
|
||||
|
||||
/* Get the thread from its handle. */
|
||||
KScopedAutoObject thread = GetCurrentProcess().GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Check that the activity is being set on a non-current thread for the current process. */
|
||||
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(), svc::ResultInvalidHandle());
|
||||
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(), svc::ResultBusy());
|
||||
|
||||
/* Set the activity. */
|
||||
R_TRY(thread->SetActivity(thread_activity));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SetProcessActivity(ams::svc::Handle process_handle, ams::svc::ProcessActivity process_activity) {
|
||||
/* Validate the activity. */
|
||||
R_UNLESS(IsValidProcessActivity(process_activity), svc::ResultInvalidEnumValue());
|
||||
|
||||
/* Get the process from its handle. */
|
||||
KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Check that the activity isn't being set on the current process. */
|
||||
R_UNLESS(process.GetPointerUnsafe() != GetCurrentProcessPointer(), svc::ResultBusy());
|
||||
|
||||
/* Set the activity. */
|
||||
R_TRY(process->SetActivity(process_activity));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ============================= 64 ABI ============================= */
|
||||
|
||||
Result SetThreadActivity64(ams::svc::Handle thread_handle, ams::svc::ThreadActivity thread_activity) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcSetThreadActivity64 was called.");
|
||||
return SetThreadActivity(thread_handle, thread_activity);
|
||||
}
|
||||
|
||||
Result SetProcessActivity64(ams::svc::Handle process_handle, ams::svc::ProcessActivity process_activity) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcSetProcessActivity64 was called.");
|
||||
return SetProcessActivity(process_handle, process_activity);
|
||||
}
|
||||
|
||||
/* ============================= 64From32 ABI ============================= */
|
||||
|
||||
Result SetThreadActivity64From32(ams::svc::Handle thread_handle, ams::svc::ThreadActivity thread_activity) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcSetThreadActivity64From32 was called.");
|
||||
return SetThreadActivity(thread_handle, thread_activity);
|
||||
}
|
||||
|
||||
Result SetProcessActivity64From32(ams::svc::Handle process_handle, ams::svc::ProcessActivity process_activity) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcSetProcessActivity64From32 was called.");
|
||||
return SetProcessActivity(process_handle, process_activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,20 +21,22 @@ namespace ams::kern::svc {
|
|||
|
||||
namespace {
|
||||
|
||||
|
||||
int32_t GetCurrentProcessorNumber() {
|
||||
return GetCurrentCoreId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ============================= 64 ABI ============================= */
|
||||
|
||||
int32_t GetCurrentProcessorNumber64() {
|
||||
MESOSPHERE_PANIC("Stubbed SvcGetCurrentProcessorNumber64 was called.");
|
||||
return GetCurrentProcessorNumber();
|
||||
}
|
||||
|
||||
/* ============================= 64From32 ABI ============================= */
|
||||
|
||||
int32_t GetCurrentProcessorNumber64From32() {
|
||||
MESOSPHERE_PANIC("Stubbed SvcGetCurrentProcessorNumber64From32 was called.");
|
||||
return GetCurrentProcessorNumber();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue