Minor fix of sys_ppu_thread_yield return value

Account for a special case where threads were rotated but no context
switch was made.
This commit is contained in:
Eladash 2020-03-18 21:44:58 +02:00 committed by Ivan
parent 7be35315da
commit b11e8f8b8d
3 changed files with 27 additions and 9 deletions

View file

@ -1162,17 +1162,35 @@ bool lv2_obj::awake_unlocked(cpu_thread* cpu, s32 prio)
if (const auto ppu = g_ppu[i]; ppu == cpu) if (const auto ppu = g_ppu[i]; ppu == cpu)
{ {
if (g_ppu[i + 1]->prio != ppu->prio) std::size_t j = i + 1;
for (; j < g_ppu.size(); j++)
{ {
return false; if (g_ppu[j]->prio != ppu->prio)
}
else
{ {
g_ppu.erase(g_ppu.cbegin() + i);
ppu->start_time = get_guest_system_time();
break; break;
} }
} }
if (j == i + 1)
{
// Empty 'same prio' threads list
return false;
}
// Rotate current thread to the last position of the 'same prio' threads list
std::rotate(g_ppu.begin() + i, g_ppu.begin() + i + 1, g_ppu.begin() + j);
if (j <= g_cfg.core.ppu_threads + 0u)
{
// Threads were rotated, but no context switch was made
return false;
}
ppu->start_time = get_guest_system_time();
cpu = nullptr; // Disable current thread enqueing, also enable threads list enqueing
break;
}
} }
} }
case enqueue_cmd: case enqueue_cmd:
@ -1227,9 +1245,9 @@ bool lv2_obj::awake_unlocked(cpu_thread* cpu, s32 prio)
} }
// Remove pending if necessary // Remove pending if necessary
if (!g_pending.empty() && cpu && cpu == get_current_cpu_thread()) if (!g_pending.empty() && ((cpu && cpu == get_current_cpu_thread()) || prio == yield_cmd))
{ {
unqueue(g_pending, cpu); unqueue(g_pending, get_current_cpu_thread());
} }
// Suspend threads if necessary // Suspend threads if necessary

View file

@ -82,7 +82,7 @@ s32 sys_ppu_thread_yield(ppu_thread& ppu)
{ {
sys_ppu_thread.trace("sys_ppu_thread_yield()"); sys_ppu_thread.trace("sys_ppu_thread_yield()");
// Return 1 on no-op, 0 on successful context switch // Return 0 on successful context switch, 1 otherwise
return +!lv2_obj::yield(ppu); return +!lv2_obj::yield(ppu);
} }

View file

@ -159,7 +159,7 @@ public:
return awake_unlocked(thread, prio); return awake_unlocked(thread, prio);
} }
// Returns true and success, false if did nothing // Returns true on successful context switch, false otherwise
static bool yield(cpu_thread& thread) static bool yield(cpu_thread& thread)
{ {
vm::temporary_unlock(thread); vm::temporary_unlock(thread);