mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +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;
|
return this->is_suspended;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr void SetSuspended(bool suspended) {
|
||||||
|
this->is_suspended = suspended;
|
||||||
|
}
|
||||||
|
|
||||||
Result Terminate();
|
Result Terminate();
|
||||||
|
|
||||||
constexpr bool IsTerminated() const {
|
constexpr bool IsTerminated() const {
|
||||||
|
@ -257,6 +261,8 @@ namespace ams::kern {
|
||||||
|
|
||||||
Result Reset();
|
Result Reset();
|
||||||
|
|
||||||
|
Result SetActivity(ams::svc::ProcessActivity activity);
|
||||||
|
|
||||||
void SetPreemptionState();
|
void SetPreemptionState();
|
||||||
|
|
||||||
Result SignalToAddress(KProcessAddress address) {
|
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 u32 GetSuspendFlags() const { return this->suspend_allowed_flags & this->suspend_request_flags; }
|
||||||
constexpr bool IsSuspended() const { return this->GetSuspendFlags() != 0; }
|
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 RequestSuspend(SuspendType type);
|
||||||
void Resume(SuspendType type);
|
void Resume(SuspendType type);
|
||||||
void TrySuspend();
|
void TrySuspend();
|
||||||
void Continue();
|
void Continue();
|
||||||
|
|
||||||
|
Result SetActivity(ams::svc::ThreadActivity activity);
|
||||||
|
|
||||||
void ContinueIfHasKernelWaiters() {
|
void ContinueIfHasKernelWaiters() {
|
||||||
if (this->GetNumKernelWaiters() > 0) {
|
if (this->GetNumKernelWaiters() > 0) {
|
||||||
this->Continue();
|
this->Continue();
|
||||||
|
|
|
@ -879,6 +879,48 @@ namespace ams::kern {
|
||||||
return ResultSuccess();
|
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) {
|
KProcess::State KProcess::SetDebugObject(void *debug_object) {
|
||||||
/* Attaching should only happen to non-null objects while the scheduler is locked. */
|
/* Attaching should only happen to non-null objects while the scheduler is locked. */
|
||||||
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
||||||
|
|
|
@ -450,6 +450,7 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ASSERT(this->parent != nullptr);
|
MESOSPHERE_ASSERT(this->parent != nullptr);
|
||||||
MESOSPHERE_ASSERT(affinity_mask != 0);
|
MESOSPHERE_ASSERT(affinity_mask != 0);
|
||||||
{
|
{
|
||||||
|
KScopedLightLock lk(this->activity_pause_lock);
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
MESOSPHERE_ASSERT(this->num_core_migration_disables >= 0);
|
MESOSPHERE_ASSERT(this->num_core_migration_disables >= 0);
|
||||||
|
|
||||||
|
@ -491,6 +492,8 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Paused waiter list. */
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +613,38 @@ namespace ams::kern {
|
||||||
KScheduler::OnThreadStateChanged(this, old_state);
|
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) {
|
void KThread::AddWaiterImpl(KThread *thread) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
||||||
|
|
|
@ -21,28 +21,81 @@ namespace ams::kern::svc {
|
||||||
|
|
||||||
namespace {
|
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 ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
|
||||||
Result SetThreadActivity64(ams::svc::Handle thread_handle, ams::svc::ThreadActivity thread_activity) {
|
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) {
|
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 ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
|
||||||
Result SetThreadActivity64From32(ams::svc::Handle thread_handle, ams::svc::ThreadActivity thread_activity) {
|
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) {
|
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 {
|
namespace {
|
||||||
|
|
||||||
|
int32_t GetCurrentProcessorNumber() {
|
||||||
|
return GetCurrentCoreId();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64 ABI ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
|
||||||
int32_t GetCurrentProcessorNumber64() {
|
int32_t GetCurrentProcessorNumber64() {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcGetCurrentProcessorNumber64 was called.");
|
return GetCurrentProcessorNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64From32 ABI ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
|
||||||
int32_t GetCurrentProcessorNumber64From32() {
|
int32_t GetCurrentProcessorNumber64From32() {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcGetCurrentProcessorNumber64From32 was called.");
|
return GetCurrentProcessorNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue