mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-13 15:19:11 +00:00
The way to Unity, pt.3 (#1681)
This commit is contained in:
@@ -132,6 +132,33 @@ public:
|
||||
m_bits &= bits;
|
||||
}
|
||||
|
||||
void Cancel(u64 setPattern, int* numWaitThreads) {
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
while (m_status != Status::Set) {
|
||||
m_mutex.unlock();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
if (numWaitThreads) {
|
||||
*numWaitThreads = m_waiting_threads;
|
||||
}
|
||||
|
||||
m_status = Status::Canceled;
|
||||
m_bits = setPattern;
|
||||
|
||||
m_cond_var.notify_all();
|
||||
|
||||
while (m_waiting_threads > 0) {
|
||||
m_mutex.unlock();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
m_status = Status::Set;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class Status { Set, Canceled, Deleted };
|
||||
|
||||
@@ -232,7 +259,8 @@ int PS4_SYSV_ABI sceKernelClearEventFlag(OrbisKernelEventFlag ef, u64 bitPattern
|
||||
|
||||
int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPattern,
|
||||
int* pNumWaitThreads) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
LOG_DEBUG(Kernel_Event, "called");
|
||||
ef->Cancel(setPattern, pNumWaitThreads);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#include "common/ntapi.h"
|
||||
#else
|
||||
#include <signal.h>
|
||||
#endif
|
||||
@@ -64,6 +65,34 @@ void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
|
||||
handler(POSIX_SIGUSR1, &ctx);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ExceptionHandler(void* arg1, void* arg2, void* arg3, PCONTEXT context) {
|
||||
const char* thrName = (char*)arg1;
|
||||
LOG_INFO(Lib_Kernel, "Exception raised successfully on thread '{}'", thrName);
|
||||
const auto handler = Handlers[POSIX_SIGUSR1];
|
||||
if (handler) {
|
||||
auto ctx = Ucontext{};
|
||||
ctx.uc_mcontext.mc_r8 = context->R8;
|
||||
ctx.uc_mcontext.mc_r9 = context->R9;
|
||||
ctx.uc_mcontext.mc_r10 = context->R10;
|
||||
ctx.uc_mcontext.mc_r11 = context->R11;
|
||||
ctx.uc_mcontext.mc_r12 = context->R12;
|
||||
ctx.uc_mcontext.mc_r13 = context->R13;
|
||||
ctx.uc_mcontext.mc_r14 = context->R14;
|
||||
ctx.uc_mcontext.mc_r15 = context->R15;
|
||||
ctx.uc_mcontext.mc_rdi = context->Rdi;
|
||||
ctx.uc_mcontext.mc_rsi = context->Rsi;
|
||||
ctx.uc_mcontext.mc_rbp = context->Rbp;
|
||||
ctx.uc_mcontext.mc_rbx = context->Rbx;
|
||||
ctx.uc_mcontext.mc_rdx = context->Rdx;
|
||||
ctx.uc_mcontext.mc_rax = context->Rax;
|
||||
ctx.uc_mcontext.mc_rcx = context->Rcx;
|
||||
ctx.uc_mcontext.mc_rsp = context->Rsp;
|
||||
ctx.uc_mcontext.mc_fs = context->SegFs;
|
||||
ctx.uc_mcontext.mc_gs = context->SegGs;
|
||||
handler(POSIX_SIGUSR1, &ctx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) {
|
||||
@@ -73,9 +102,7 @@ int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelException
|
||||
}
|
||||
ASSERT_MSG(!Handlers[POSIX_SIGUSR1], "Invalid parameters");
|
||||
Handlers[POSIX_SIGUSR1] = handler;
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
struct sigaction act = {};
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
act.sa_sigaction = reinterpret_cast<decltype(act.sa_sigaction)>(SigactionHandler);
|
||||
@@ -91,9 +118,7 @@ int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
|
||||
}
|
||||
ASSERT_MSG(Handlers[POSIX_SIGUSR1], "Invalid parameters");
|
||||
Handlers[POSIX_SIGUSR1] = nullptr;
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
struct sigaction act = {};
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
act.sa_sigaction = nullptr;
|
||||
@@ -103,13 +128,18 @@ int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
|
||||
LOG_ERROR(Lib_Kernel, "Raising exception");
|
||||
LOG_WARNING(Lib_Kernel, "Raising exception on thread '{}'", thread->name);
|
||||
ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!");
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
#ifndef _WIN64
|
||||
pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_thr.GetHandle());
|
||||
pthread_kill(pthr, SIGUSR2);
|
||||
#else
|
||||
USER_APC_OPTION option;
|
||||
option.UserApcFlags = QueueUserApcFlagsSpecialUserApc;
|
||||
|
||||
u64 res = NtQueueApcThreadEx(reinterpret_cast<HANDLE>(thread->native_thr.GetHandle()), option,
|
||||
ExceptionHandler, (void*)thread->name.c_str(), nullptr, nullptr);
|
||||
ASSERT(res == 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -540,6 +540,8 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("onNY9Byn-W8", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_join));
|
||||
LIB_FUNCTION("P41kTWUS3EI", "libkernel", 1, "libkernel", 1, 1,
|
||||
ORBIS(posix_pthread_getschedparam));
|
||||
LIB_FUNCTION("oIRFTjoILbg", "libkernel", 1, "libkernel", 1, 1,
|
||||
ORBIS(posix_pthread_setschedparam));
|
||||
LIB_FUNCTION("How7B8Oet6k", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_getname_np));
|
||||
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, posix_pthread_exit);
|
||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
||||
|
||||
@@ -111,15 +111,19 @@ public:
|
||||
BinarySemaphore sem;
|
||||
u32 priority;
|
||||
s32 need_count;
|
||||
std::string thr_name;
|
||||
bool was_signaled{};
|
||||
bool was_deleted{};
|
||||
bool was_cancled{};
|
||||
|
||||
explicit WaitingThread(s32 need_count, bool is_fifo) : sem{0}, need_count{need_count} {
|
||||
explicit WaitingThread(s32 need_count, bool is_fifo)
|
||||
: sem{0}, priority{0}, need_count{need_count} {
|
||||
// Retrieve calling thread priority for sorting into waiting threads list.
|
||||
if (!is_fifo) {
|
||||
priority = g_curthread->attr.prio;
|
||||
}
|
||||
|
||||
thr_name = g_curthread->name;
|
||||
}
|
||||
|
||||
int GetResult(bool timed_out) {
|
||||
@@ -232,6 +236,7 @@ int PS4_SYSV_ABI sceKernelDeleteSema(OrbisKernelSema sem) {
|
||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
sem->Delete();
|
||||
delete sem;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
@@ -246,6 +251,16 @@ int PS4_SYSV_ABI posix_sem_init(PthreadSem** sem, int pshared, u32 value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_destroy(PthreadSem** sem) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
delete *sem;
|
||||
*sem = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_wait(PthreadSem** sem) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
@@ -296,16 +311,6 @@ int PS4_SYSV_ABI posix_sem_post(PthreadSem** sem) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_destroy(PthreadSem** sem) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
delete *sem;
|
||||
*sem = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sem_getvalue(PthreadSem** sem, int* sval) {
|
||||
if (sem == nullptr || *sem == nullptr) {
|
||||
*__Error() = POSIX_EINVAL;
|
||||
@@ -317,6 +322,77 @@ int PS4_SYSV_ABI posix_sem_getvalue(PthreadSem** sem, int* sval) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemInit(PthreadSem** sem, int flag, u32 value, const char* name) {
|
||||
if (flag != 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
s32 ret = posix_sem_init(sem, 0, value);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemDestroy(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_destroy(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemWait(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_wait(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemTrywait(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_trywait(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemTimedwait(PthreadSem** sem, u32 usec) {
|
||||
OrbisKernelTimespec time{};
|
||||
time.tv_sec = usec / 1000000;
|
||||
time.tv_nsec = (usec % 1000000) * 1000;
|
||||
|
||||
s32 ret = posix_sem_timedwait(sem, &time);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemPost(PthreadSem** sem) {
|
||||
s32 ret = posix_sem_post(sem);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI scePthreadSemGetvalue(PthreadSem** sem, int* sval) {
|
||||
s32 ret = posix_sem_getvalue(sem, sval);
|
||||
if (ret != 0) {
|
||||
return ErrnoToSceKernelError(*__Error());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterSemaphore(Core::Loader::SymbolsResolver* sym) {
|
||||
// Orbis
|
||||
LIB_FUNCTION("188x57JYp0g", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateSema);
|
||||
@@ -328,12 +404,20 @@ void RegisterSemaphore(Core::Loader::SymbolsResolver* sym) {
|
||||
|
||||
// Posix
|
||||
LIB_FUNCTION("pDuPEf3m4fI", "libScePosix", 1, "libkernel", 1, 1, posix_sem_init);
|
||||
LIB_FUNCTION("cDW233RAwWo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_destroy);
|
||||
LIB_FUNCTION("YCV5dGGBcCo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_wait);
|
||||
LIB_FUNCTION("WBWzsRifCEA", "libScePosix", 1, "libkernel", 1, 1, posix_sem_trywait);
|
||||
LIB_FUNCTION("w5IHyvahg-o", "libScePosix", 1, "libkernel", 1, 1, posix_sem_timedwait);
|
||||
LIB_FUNCTION("IKP8typ0QUk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_post);
|
||||
LIB_FUNCTION("cDW233RAwWo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_destroy);
|
||||
LIB_FUNCTION("Bq+LRV-N6Hk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_getvalue);
|
||||
|
||||
LIB_FUNCTION("GEnUkDZoUwY", "libkernel", 1, "libkernel", 1, 1, scePthreadSemInit);
|
||||
LIB_FUNCTION("Vwc+L05e6oE", "libkernel", 1, "libkernel", 1, 1, scePthreadSemDestroy);
|
||||
LIB_FUNCTION("C36iRE0F5sE", "libkernel", 1, "libkernel", 1, 1, scePthreadSemWait);
|
||||
LIB_FUNCTION("H2a+IN9TP0E", "libkernel", 1, "libkernel", 1, 1, scePthreadSemTrywait);
|
||||
LIB_FUNCTION("fjN6NQHhK8k", "libkernel", 1, "libkernel", 1, 1, scePthreadSemTimedwait);
|
||||
LIB_FUNCTION("aishVAiFaYM", "libkernel", 1, "libkernel", 1, 1, scePthreadSemPost);
|
||||
LIB_FUNCTION("DjpBvGlaWbQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSemGetvalue);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
||||
Reference in New Issue
Block a user