Properly wake semaphores in priority order.
This commit is contained in:
parent
4c510b5649
commit
4a56873541
3 changed files with 14 additions and 31 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue