kern: finish SvcGetInfo

This commit is contained in:
Michael Scire 2020-07-24 05:44:52 -07:00 committed by SciresM
parent fd9b986938
commit 695b82b945
4 changed files with 66 additions and 4 deletions

View file

@ -82,6 +82,14 @@ namespace ams::kern {
this->ScheduleOnInterrupt();
}
}
ALWAYS_INLINE KThread *GetIdleThread() const {
return this->idle_thread;
}
ALWAYS_INLINE s64 GetLastContextSwitchTime() const {
return this->last_context_switch_time;
}
private:
/* Static private API. */
static ALWAYS_INLINE bool IsSchedulerUpdateNeeded() { return s_scheduler_update_needed; }

View file

@ -427,8 +427,18 @@ namespace ams::kern {
constexpr void SetDebugAttached() { this->debug_attached = true; }
constexpr bool IsAttachedToDebugger() const { return this->debug_attached; }
void AddCpuTime(s64 amount) {
void AddCpuTime(s32 core_id, s64 amount) {
this->cpu_time += amount;
/* TODO: Debug kernels track per-core tick counts. Should we? */
}
s64 GetCpuTime() const { return this->cpu_time; }
s64 GetCpuTime(s32 core_id) const {
MESOSPHERE_ABORT_UNLESS(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
/* TODO: Debug kernels track per-core tick counts. Should we? */
return 0;
}
constexpr u32 GetSuspendFlags() const { return this->suspend_allowed_flags & this->suspend_request_flags; }

View file

@ -232,7 +232,7 @@ namespace ams::kern {
const s64 prev_tick = this->last_context_switch_time;
const s64 cur_tick = KHardwareTimer::GetTick();
const s64 tick_diff = cur_tick - prev_tick;
cur_thread->AddCpuTime(tick_diff);
cur_thread->AddCpuTime(this->core_id, tick_diff);
if (cur_process != nullptr) {
cur_process->AddCpuTime(tick_diff);
}

View file

@ -153,6 +153,19 @@ namespace ams::kern::svc {
}
}
break;
case ams::svc::InfoType_IdleTickCount:
{
/* Verify the input handle is invalid. */
R_UNLESS(handle == ams::svc::InvalidHandle, svc::ResultInvalidHandle());
/* Verify the requested core is valid. */
const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype == static_cast<u64>(GetCurrentCoreId()));
R_UNLESS(core_valid, svc::ResultInvalidCombination());
/* Get the idle tick count. */
*out = Kernel::GetScheduler().GetIdleThread()->GetCpuTime();
}
break;
case ams::svc::InfoType_RandomEntropy:
{
/* Verify the input handle is invalid. */
@ -165,11 +178,42 @@ namespace ams::kern::svc {
*out = GetCurrentProcess().GetRandomEntropy(info_subtype);
}
break;
case ams::svc::InfoType_ThreadTickCount:
{
/* Verify the requested core is valid. */
const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype < cpu::NumCores);
R_UNLESS(core_valid, svc::ResultInvalidCombination());
/* Get the thread from its handle. */
KScopedAutoObject thread = GetCurrentProcess().GetHandleTable().GetObject<KThread>(handle);
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidHandle());
/* Get the tick count. */
s64 tick_count;
if (info_subtype == static_cast<u64>(-1ul)) {
tick_count = thread->GetCpuTime();
if (GetCurrentThreadPointer() == thread.GetPointerUnsafe()) {
const s64 cur_tick = KHardwareTimer::GetTick();
const s64 prev_switch = Kernel::GetScheduler().GetLastContextSwitchTime();
tick_count += (cur_tick - prev_switch);
}
} else {
tick_count = thread->GetCpuTime(static_cast<s32>(info_subtype));
if (GetCurrentThreadPointer() == thread.GetPointerUnsafe() && static_cast<s32>(info_subtype) == GetCurrentCoreId()) {
const s64 cur_tick = KHardwareTimer::GetTick();
const s64 prev_switch = Kernel::GetScheduler().GetLastContextSwitchTime();
tick_count += (cur_tick - prev_switch);
}
}
/* Set the output. */
*out = tick_count;
}
break;
default:
{
/* For debug, until all infos are implemented. */
/* For debug, log the invalid info call. */
MESOSPHERE_LOG("GetInfo(%p, %u, %08x, %lu) was called\n", out, static_cast<u32>(info_type), static_cast<u32>(handle), info_subtype);
MESOSPHERE_UNIMPLEMENTED();
}
return svc::ResultInvalidEnumValue();
}