Properly wake semaphores in priority order.

This commit is contained in:
Unknown W. Brackets 2013-01-17 00:45:13 -08:00
parent 4c510b5649
commit 4a56873541
3 changed files with 14 additions and 31 deletions

View file

@ -135,26 +135,6 @@ bool __KernelClearSemaThreads(Semaphore *s, int reason)
return wokeThreads;
}
std::vector<SceUID>::iterator __KernelSemaFindPriority(std::vector<SceUID> &waiting, std::vector<SceUID>::iterator begin)
{
_dbg_assert_msg_(HLE, !waiting.empty(), "__KernelSemaFindPriority: Trying to find best of no threads.");
std::vector<SceUID>::iterator iter, end, best = waiting.end();
u32 best_prio = 0xFFFFFFFF;
for (iter = begin, end = waiting.end(); iter != end; ++iter)
{
u32 iter_prio = __KernelGetThreadPrio(*iter);
if (iter_prio < best_prio)
{
best = iter;
best_prio = iter_prio;
}
}
_dbg_assert_msg_(HLE, best != waiting.end(), "__KernelSemaFindPriority: Returning invalid best thread.");
return best;
}
int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
{
DEBUG_LOG(HLE, "sceKernelCancelSema(%i)", id);
@ -273,19 +253,16 @@ int sceKernelSignalSema(SceUID id, int signal)
s->ns.currentCount += signal;
DEBUG_LOG(HLE, "sceKernelSignalSema(%i, %i) (old: %i, new: %i)", id, signal, oldval, s->ns.currentCount);
bool wokeThreads = false;
std::vector<SceUID>::iterator iter, end, best;
retry:
for (iter = s->waitingThreads.begin(), end = s->waitingThreads.end(); iter != end; ++iter)
{
if ((s->ns.attr & PSP_SEMA_ATTR_PRIORITY) != 0)
best = __KernelSemaFindPriority(s->waitingThreads, iter);
else
best = iter;
if ((s->ns.attr & PSP_SEMA_ATTR_PRIORITY) != 0)
std::stable_sort(s->waitingThreads.begin(), s->waitingThreads.end(), __KernelThreadSortPriority);
if (__KernelUnlockSemaForThread(s, *best, error, 0, wokeThreads))
bool wokeThreads = false;
retry:
for (auto iter = s->waitingThreads.begin(), end = s->waitingThreads.end(); iter != end; ++iter)
{
if (__KernelUnlockSemaForThread(s, *iter, error, 0, wokeThreads))
{
s->waitingThreads.erase(best);
s->waitingThreads.erase(iter);
goto retry;
}
}