sceKernelPollSema fix

This commit is contained in:
georgemoralis 2024-06-12 18:01:04 +03:00
parent 24446bcc32
commit 834d01662d

View File

@ -5,8 +5,8 @@
#include <boost/intrusive/list.hpp> #include <boost/intrusive/list.hpp>
#include <pthread.h> #include <pthread.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/scope_exit.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/scope_exit.h"
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
@ -18,9 +18,7 @@ using ListBaseHook =
class Semaphore { class Semaphore {
public: public:
Semaphore(s32 init_count, s32 max_count, bool is_fifo) Semaphore(s32 init_count, s32 max_count, bool is_fifo)
: token_count{init_count}, max_count{max_count}, is_fifo{is_fifo} { : token_count{init_count}, max_count{max_count}, is_fifo{is_fifo} {}
}
bool Wait(bool can_block, s32 need_count, u64* timeout) { bool Wait(bool can_block, s32 need_count, u64* timeout) {
if (HasAvailableTokens(need_count)) { if (HasAvailableTokens(need_count)) {
@ -33,7 +31,9 @@ public:
// Create waiting thread object and add it into the list of waiters. // Create waiting thread object and add it into the list of waiters.
WaitingThread waiter{need_count, is_fifo}; WaitingThread waiter{need_count, is_fifo};
AddWaiter(waiter); AddWaiter(waiter);
SCOPE_EXIT { PopWaiter(waiter); }; SCOPE_EXIT {
PopWaiter(waiter);
};
// Perform the wait. // Perform the wait.
return waiter.Wait(timeout); return waiter.Wait(timeout);
@ -87,7 +87,8 @@ private:
const auto start = std::chrono::high_resolution_clock::now(); const auto start = std::chrono::high_resolution_clock::now();
const auto status = cv.wait_for(lk, std::chrono::microseconds(*timeout)); const auto status = cv.wait_for(lk, std::chrono::microseconds(*timeout));
const auto end = std::chrono::high_resolution_clock::now(); const auto end = std::chrono::high_resolution_clock::now();
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); const auto time =
std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
*timeout -= time; *timeout -= time;
return status != std::cv_status::timeout; return status != std::cv_status::timeout;
} }
@ -126,9 +127,9 @@ private:
return false; return false;
} }
using WaitingThreads = boost::intrusive::list<WaitingThread, using WaitingThreads =
boost::intrusive::base_hook<ListBaseHook>, boost::intrusive::list<WaitingThread, boost::intrusive::base_hook<ListBaseHook>,
boost::intrusive::constant_time_size<false>>; boost::intrusive::constant_time_size<false>>;
WaitingThreads wait_list; WaitingThreads wait_list;
std::atomic<s32> token_count; std::atomic<s32> token_count;
std::mutex mutex; std::mutex mutex;
@ -138,7 +139,7 @@ private:
using OrbisKernelSema = Semaphore*; using OrbisKernelSema = Semaphore*;
s32 PS4_SYSV_ABI sceKernelCreateSema(OrbisKernelSema *sem, const char *pName, u32 attr, s32 PS4_SYSV_ABI sceKernelCreateSema(OrbisKernelSema* sem, const char* pName, u32 attr,
s32 initCount, s32 maxCount, const void* pOptParam) { s32 initCount, s32 maxCount, const void* pOptParam) {
if (!pName || attr > 2 || initCount < 0 || maxCount <= 0 || initCount > maxCount) { if (!pName || attr > 2 || initCount < 0 || maxCount <= 0 || initCount > maxCount) {
LOG_ERROR(Lib_Kernel, "Semaphore creation parameters are invalid!"); LOG_ERROR(Lib_Kernel, "Semaphore creation parameters are invalid!");
@ -161,7 +162,9 @@ s32 PS4_SYSV_ABI sceKernelSignalSema(OrbisKernelSema sem, s32 signalCount) {
} }
s32 PS4_SYSV_ABI sceKernelPollSema(OrbisKernelSema sem, s32 needCount) { s32 PS4_SYSV_ABI sceKernelPollSema(OrbisKernelSema sem, s32 needCount) {
ASSERT(sem->Wait(false, needCount, nullptr)); if (!sem->Wait(false, needCount, nullptr)) {
return ORBIS_KERNEL_ERROR_EBUSY;
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -169,6 +172,7 @@ void SemaphoreSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("188x57JYp0g", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateSema); LIB_FUNCTION("188x57JYp0g", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateSema);
LIB_FUNCTION("Zxa0VhQVTsk", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitSema); LIB_FUNCTION("Zxa0VhQVTsk", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitSema);
LIB_FUNCTION("4czppHBiriw", "libkernel", 1, "libkernel", 1, 1, sceKernelSignalSema); LIB_FUNCTION("4czppHBiriw", "libkernel", 1, "libkernel", 1, 1, sceKernelSignalSema);
LIB_FUNCTION("12wOHk8ywb0", "libkernel", 1, "libkernel", 1, 1, sceKernelPollSema);
} }
} // namespace Libraries::Kernel } // namespace Libraries::Kernel