mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-30 07:42:13 +00:00
kern: implement SvcSleepThread for ns > 0
This commit is contained in:
parent
f37eda6b86
commit
ca9327a120
5 changed files with 79 additions and 3 deletions
|
@ -122,8 +122,11 @@ namespace ams::kern {
|
||||||
static NOINLINE void OnThreadPriorityChanged(KThread *thread, s32 old_priority);
|
static NOINLINE void OnThreadPriorityChanged(KThread *thread, s32 old_priority);
|
||||||
static NOINLINE void OnThreadAffinityMaskChanged(KThread *thread, const KAffinityMask &old_affinity, s32 old_core);
|
static NOINLINE void OnThreadAffinityMaskChanged(KThread *thread, const KAffinityMask &old_affinity, s32 old_core);
|
||||||
|
|
||||||
/* TODO: Yield operations */
|
|
||||||
static NOINLINE void RotateScheduledQueue(s32 priority, s32 core_id);
|
static NOINLINE void RotateScheduledQueue(s32 priority, s32 core_id);
|
||||||
|
|
||||||
|
static NOINLINE void YieldWithoutCoreMigration();
|
||||||
|
static NOINLINE void YieldWithCoreMigration();
|
||||||
|
static NOINLINE void YieldToAnyThread();
|
||||||
private:
|
private:
|
||||||
/* Instanced private API. */
|
/* Instanced private API. */
|
||||||
void ScheduleImpl();
|
void ScheduleImpl();
|
||||||
|
|
|
@ -385,6 +385,8 @@ namespace ams::kern {
|
||||||
Result Run();
|
Result Run();
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
|
Result Sleep(s64 timeout);
|
||||||
|
|
||||||
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(this->kernel_stack_top) - 1; }
|
ALWAYS_INLINE void *GetStackTop() const { return reinterpret_cast<StackParameters *>(this->kernel_stack_top) - 1; }
|
||||||
ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; }
|
ALWAYS_INLINE void *GetKernelStackTop() const { return this->kernel_stack_top; }
|
||||||
|
|
||||||
|
|
|
@ -401,5 +401,16 @@ namespace ams::kern {
|
||||||
SetSchedulerUpdateNeeded();
|
SetSchedulerUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KScheduler::YieldWithoutCoreMigration() {
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KScheduler::YieldWithCoreMigration() {
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KScheduler::YieldToAnyThread() {
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,6 +664,35 @@ namespace ams::kern {
|
||||||
MESOSPHERE_PANIC("KThread::Exit() would return");
|
MESOSPHERE_PANIC("KThread::Exit() would return");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result KThread::Sleep(s64 timeout) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
MESOSPHERE_ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread());
|
||||||
|
MESOSPHERE_ASSERT(this == GetCurrentThreadPointer());
|
||||||
|
MESOSPHERE_ASSERT(timeout > 0);
|
||||||
|
|
||||||
|
KHardwareTimer *timer;
|
||||||
|
{
|
||||||
|
/* Setup the scheduling lock and sleep. */
|
||||||
|
KScopedSchedulerLockAndSleep slp(std::addressof(timer), this, timeout);
|
||||||
|
|
||||||
|
/* Check if the thread should terminate. */
|
||||||
|
if (this->IsTerminationRequested()) {
|
||||||
|
slp.CancelSleep();
|
||||||
|
return svc::ResultTerminationRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark the thread as waiting. */
|
||||||
|
this->SetState(KThread::ThreadState_Waiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The lock/sleep is done. */
|
||||||
|
|
||||||
|
/* Cancel the timer. */
|
||||||
|
timer->CancelTask(this);
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
void KThread::SetState(ThreadState state) {
|
void KThread::SetState(ThreadState state) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,37 @@ namespace ams::kern::svc {
|
||||||
MESOSPHERE_PANIC("Process survived call to exit");
|
MESOSPHERE_PANIC("Process survived call to exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SleepThread(int64_t ns) {
|
||||||
|
/* When the input tick is positive, sleep. */
|
||||||
|
if (AMS_LIKELY(ns > 0)) {
|
||||||
|
/* Convert the timeout from nanoseconds to ticks. */
|
||||||
|
/* NOTE: Nintendo does not use this conversion logic in WaitSynchronization... */
|
||||||
|
s64 timeout;
|
||||||
|
|
||||||
|
const ams::svc::Tick offset_tick(TimeSpan::FromNanoSeconds(ns));
|
||||||
|
if (AMS_LIKELY(offset_tick > 0)) {
|
||||||
|
timeout = KHardwareTimer::GetTick() + offset_tick + 2;
|
||||||
|
if (AMS_UNLIKELY(timeout <= 0)) {
|
||||||
|
timeout = std::numeric_limits<s64>::max();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeout = std::numeric_limits<s64>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sleep. */
|
||||||
|
/* NOTE: Nintendo does not check the result of this sleep. */
|
||||||
|
GetCurrentThread().Sleep(timeout);
|
||||||
|
} else if (ns == ams::svc::YieldType_WithoutCoreMigration) {
|
||||||
|
KScheduler::YieldWithoutCoreMigration();
|
||||||
|
} else if (ns == ams::svc::YieldType_WithCoreMigration) {
|
||||||
|
KScheduler::YieldWithCoreMigration();
|
||||||
|
} else if (ns == ams::svc::YieldType_ToAnyThread) {
|
||||||
|
KScheduler::YieldToAnyThread();
|
||||||
|
} else {
|
||||||
|
/* Nintendo does nothing at all if an otherwise invalid value is passed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result GetThreadPriority(int32_t *out_priority, ams::svc::Handle thread_handle) {
|
Result GetThreadPriority(int32_t *out_priority, ams::svc::Handle thread_handle) {
|
||||||
/* Get the thread from its handle. */
|
/* Get the thread from its handle. */
|
||||||
KScopedAutoObject thread = GetCurrentProcess().GetHandleTable().GetObject<KThread>(thread_handle);
|
KScopedAutoObject thread = GetCurrentProcess().GetHandleTable().GetObject<KThread>(thread_handle);
|
||||||
|
@ -123,7 +154,7 @@ namespace ams::kern::svc {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SleepThread64(int64_t ns) {
|
void SleepThread64(int64_t ns) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcSleepThread64 was called.");
|
return SleepThread(ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetThreadPriority64(int32_t *out_priority, ams::svc::Handle thread_handle) {
|
Result GetThreadPriority64(int32_t *out_priority, ams::svc::Handle thread_handle) {
|
||||||
|
@ -177,7 +208,7 @@ namespace ams::kern::svc {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SleepThread64From32(int64_t ns) {
|
void SleepThread64From32(int64_t ns) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcSleepThread64From32 was called.");
|
return SleepThread(ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetThreadPriority64From32(int32_t *out_priority, ams::svc::Handle thread_handle) {
|
Result GetThreadPriority64From32(int32_t *out_priority, ams::svc::Handle thread_handle) {
|
||||||
|
|
Loading…
Reference in a new issue