mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
kern: finish SvcGetInfo
This commit is contained in:
parent
fd9b986938
commit
695b82b945
4 changed files with 66 additions and 4 deletions
|
@ -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; }
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue