kern: implement 64-virtual-core interface

This commit is contained in:
Michael Scire
2020-12-01 15:54:31 -08:00
committed by SciresM
parent 3fd59b61bc
commit 28f9b534b6
8 changed files with 224 additions and 96 deletions

View File

@@ -363,7 +363,11 @@ namespace ams::kern::svc {
case ams::svc::DebugThreadParam_IdealCore:
{
/* Get the ideal core. */
*out_32 = thread->GetIdealCore();
s32 core_id;
u64 affinity_mask;
thread->GetPhysicalCoreMask(std::addressof(core_id), std::addressof(affinity_mask));
*out_32 = core_id;
}
break;
case ams::svc::DebugThreadParam_CurrentCore:
@@ -375,7 +379,11 @@ namespace ams::kern::svc {
case ams::svc::DebugThreadParam_AffinityMask:
{
/* Get the affinity mask. */
*out_32 = thread->GetAffinityMask().GetAffinityMask();
s32 core_id;
u64 affinity_mask;
thread->GetPhysicalCoreMask(std::addressof(core_id), std::addressof(affinity_mask));
*out_32 = affinity_mask;
}
break;
default:

View File

@@ -206,28 +206,35 @@ namespace ams::kern::svc {
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);
const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype < util::size(cpu::VirtualToPhysicalCoreMap));
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. */
/* Disable interrupts while we 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);
{
KScopedInterruptDisable di;
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 {
const s32 phys_core = cpu::VirtualToPhysicalCoreMap[info_subtype];
MESOSPHERE_ABORT_UNLESS(phys_core < static_cast<s32>(cpu::NumCores));
tick_count = thread->GetCpuTime(phys_core);
if (GetCurrentThreadPointer() == thread.GetPointerUnsafe() && phys_core == GetCurrentCoreId()) {
const s64 cur_tick = KHardwareTimer::GetTick();
const s64 prev_switch = Kernel::GetScheduler().GetLastContextSwitchTime();
tick_count += (cur_tick - prev_switch);
}
}
}

View File

@@ -22,7 +22,31 @@ namespace ams::kern::svc {
namespace {
int32_t GetCurrentProcessorNumber() {
return GetCurrentCoreId();
/* Setup variables to track affinity information. */
s32 current_phys_core;
u64 v_affinity_mask = 0;
/* Forever try to get the affinity. */
while (true) {
/* Update affinity information if we've run out. */
while (v_affinity_mask == 0) {
current_phys_core = GetCurrentCoreId();
v_affinity_mask = GetCurrentThread().GetVirtualAffinityMask();
if ((v_affinity_mask & (1ul << current_phys_core)) != 0) {
return current_phys_core;
}
}
/* Check the next virtual bit. */
do {
const s32 next_virt_core = static_cast<s32>(__builtin_ctzll(v_affinity_mask));
if (current_phys_core == cpu::VirtualToPhysicalCoreMap[next_virt_core]) {
return next_virt_core;
}
v_affinity_mask &= ~(1ul << next_virt_core);
} while (v_affinity_mask != 0);
}
}
}