# UNDF: UNDF-2026-000001145 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -547,3 +547,3 @@ // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. - if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) + if (mutex->waitingThreadSet.insert(threadID).second) mutex->waitingThreads.push_back(threadID); @@ -569,3 +569,3 @@ // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. - if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) + if (mutex->waitingThreadSet.insert(threadID).second) mutex->waitingThreads.push_back(threadID); @@ -950,3 +950,3 @@ // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. - if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) + if (mutex->waitingThreadSet.insert(threadID).second) mutex->waitingThreads.push_back(threadID); @@ -985,3 +985,3 @@ // May be in a tight loop timing out (where we don't remove from waitingThreads yet), don't want to add duplicates. - if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) + if (mutex->waitingThreadSet.insert(threadID).second) mutex->waitingThreads.push_back(threadID); # # CWE-407: sceKernelLockMutex / sceKernelLockMutexCB / # sceKernelLockLwMutex / sceKernelLockLwMutexCB each scan # mutex->waitingThreads vector with std::find before push_back — # O(W) per lock attempt where W = number of waiting threads. # The code comment says "May be in a tight loop timing out" — that # tight-loop scenario is exactly where O(W) dedup compounds: # T attempts * W waiters = O(T*W) total work per timeout cycle. # Fix: maintain parallel unordered_set waitingThreadSet for # O(1) dedup; remove from set wherever waitingThreads is cleared/erased. # Severity: MEDIUM — mutex lock is a hot HLE synchronization path; # games with thread pools or producer-consumer patterns will trigger # this on every lock contention timeout cycle. # Sites: sceKernelLockMutex (line 548), sceKernelLockMutexCB (line 570), # sceKernelLockLwMutex (line 951), sceKernelLockLwMutexCB (line 986).