Files
AnyPS5/core/libs/tests/SemaphoreTrace.cpp
T
Yunus Shaikh 0a353f80ef fix(libkernel): queue semaphore waiters by thread priority for SCE_KERNEL_SEMA_ATTR_TH_PRIO
A semaphore created with attribute 0x02 inserts a waiter before the first queued waiter with a lower priority, so the signal hands tokens to higher-priority threads first and to equal ones in arrival order. guest_semaphore_handoff also checks two waiters: the skip of one that needs more than is left, and the order for both attributes.
2026-10-21 16:42:42 -07:00

37 lines
1.3 KiB
C++

#include "prx/libkernel/Semaphore/include/Semaphore.hpp"
#include "prx/libkernel/Time/include/Time.hpp"
#include <atomic>
#include <chrono>
#include <thread>
extern "C" void KernelTraceWait_nid_postfix(const char*, const void*, std::uint64_t, bool) {}
extern "C" Pthread APS5_VABI scePthreadSelf() { return nullptr; }
extern "C" int APS5_VABI scePthreadGetprio(Pthread, int*) { return -1; }
int main() {
KernelSema sem = nullptr;
if (sceKernelCreateSema(&sem, "trace", 0, 0, 1, nullptr) != KERNEL_SEMA_OK) return 1;
std::atomic<int> result{-1};
std::thread waiter([&] { result.store(sceKernelWaitSema(sem, 1, nullptr)); });
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2);
for (;;) {
{
std::lock_guard lock(sem->mutex);
if (sem->waiterCount != 0) break;
}
if (std::chrono::steady_clock::now() >= deadline) {
sceKernelSignalSema(sem, 1);
waiter.join();
sceKernelDeleteSema(sem);
return 2;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
const int signaled = sceKernelSignalSema(sem, 1);
waiter.join();
const int deleted = sceKernelDeleteSema(sem);
return signaled == KERNEL_SEMA_OK && result.load() == KERNEL_SEMA_OK && deleted == KERNEL_SEMA_OK ? 0 : 3;
}