diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index 42cb2cbb..a43c9da8 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -923,9 +923,9 @@ int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) { } int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex) { + cond = static_cast(createCond(cond)); if (cond == nullptr || *cond == nullptr) { - // return SCE_KERNEL_ERROR_EINVAL; - cond = static_cast(createCond(cond)); // check this. Kero Blaster. + return SCE_KERNEL_ERROR_EINVAL; } if (mutex == nullptr || *mutex == nullptr) { return SCE_KERNEL_ERROR_EINVAL; @@ -946,6 +946,35 @@ int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex } } +int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec) { + cond = static_cast(createCond(cond)); + if (cond == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + if (mutex == nullptr || *mutex == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + timespec* time; + time->tv_sec = usec / 1000000; + time->tv_nsec = ((usec % 1000000) * 1000); + int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, time); + + LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result); + + switch (result) { + case 0: + return SCE_OK; + case ETIMEDOUT: + return SCE_KERNEL_ERROR_ETIMEDOUT; + case EINTR: + return SCE_KERNEL_ERROR_EINTR; + case EAGAIN: + return SCE_KERNEL_ERROR_EAGAIN; + default: + return SCE_KERNEL_ERROR_EINVAL; + } +} + int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr) { if (attr == nullptr) { return SCE_KERNEL_ERROR_EINVAL; @@ -991,6 +1020,23 @@ int PS4_SYSV_ABI scePthreadEqual(ScePthread thread1, ScePthread thread2) { return (thread1 == thread2 ? 1 : 0); } +int PS4_SYSV_ABI ps4_gettimeofday(SceKernelTimespec* tp /*, timezone */) { + if (tp == nullptr) { + return -1; + } + LOG_INFO(Kernel_Pthread, "ps4_gettimeofday"); + + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + auto seconds = std::chrono::duration_cast(duration); + auto nanoseconds = std::chrono::duration_cast(duration - seconds); + + tp->tv_sec = static_cast(seconds.count()); + tp->tv_nsec = static_cast(nanoseconds.count()); + + return 0; +} + void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy); LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate); @@ -1027,6 +1073,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit); LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast); LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", 1, 1, scePthreadCondWait); + LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait); LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy); LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal); // posix calls @@ -1039,11 +1086,14 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, clock_gettime); LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, clock_gettime); LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, nanosleep); + LIB_FUNCTION("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1, nanosleep); // CUSA18841 // openorbis weird functions LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock); LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock); LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); + + LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, ps4_gettimeofday); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index b086a7e4..9e866100 100644 --- a/src/core/libraries/kernel/thread_management.h +++ b/src/core/libraries/kernel/thread_management.h @@ -160,6 +160,9 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat const char* name); int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr); int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); +int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex); +int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec); +int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr); /**** * Posix calls */ diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index 6bf6a91b..f558dda6 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -75,8 +75,23 @@ int PS4_SYSV_ABI sceRtcGetCurrentClock() { return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime() { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); +int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime) { + auto now = std::chrono::system_clock::now(); + auto now_ns = std::chrono::time_point_cast(now); + auto epoch = now_ns.time_since_epoch(); + auto micros = std::chrono::duration_cast(epoch); + + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + std::tm local_tm = *std::localtime(&now_time_t); + + pTime->year = local_tm.tm_year + 1900; + pTime->month = local_tm.tm_mon + 1; + pTime->day = local_tm.tm_mday; + pTime->hour = local_tm.tm_hour; + pTime->minute = local_tm.tm_min; + pTime->second = local_tm.tm_sec; + pTime->microsecond = micros.count() % 1000000; + return ORBIS_OK; } @@ -102,9 +117,13 @@ int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) { return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcGetDayOfWeek() { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) { + std::tm timeinfo = {0}; + timeinfo.tm_year = year - 1900; + timeinfo.tm_mon = month - 1; + timeinfo.tm_mday = day; + std::mktime(&timeinfo); + return timeinfo.tm_wday; } int PS4_SYSV_ABI sceRtcGetDaysInMonth() { diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index ee6afa70..7416afd4 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -15,6 +15,16 @@ struct OrbisRtcTick { u64 tick; }; +struct OrbisRtcDateTime { + u16 year; + u16 month; + u16 day; + u16 hour; + u16 minute; + u16 second; + u16 microsecond; +}; + int PS4_SYSV_ABI sceRtcCheckValid(); int PS4_SYSV_ABI sceRtcCompareTick(); int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc(); @@ -28,12 +38,12 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(); int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime(); int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick(); int PS4_SYSV_ABI sceRtcGetCurrentClock(); -int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(); +int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime); int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick(); int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(); int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(); int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick); -int PS4_SYSV_ABI sceRtcGetDayOfWeek(); +int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day); int PS4_SYSV_ABI sceRtcGetDaysInMonth(); int PS4_SYSV_ABI sceRtcGetDosTime(); int PS4_SYSV_ABI sceRtcGetTick();