mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-03 16:02:26 +00:00
Kernel: Changes to scekernelUsleep to improve precision.
This commit is contained in:
parent
74c2c6c74f
commit
d1604bc776
@ -72,17 +72,13 @@ int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
timespec start;
|
struct timespec req, rem;
|
||||||
timespec remain;
|
req.tv_sec = microseconds / 1000000;
|
||||||
start.tv_sec = microseconds / 1000000;
|
req.tv_nsec = (microseconds % 1000000) * 1000;
|
||||||
start.tv_nsec = (microseconds % 1000000) * 1000;
|
while (nanosleep(&req, &rem) == -1) {
|
||||||
timespec* requested = &start;
|
req = rem;
|
||||||
int ret = 0;
|
}
|
||||||
do {
|
return 0;
|
||||||
ret = nanosleep(requested, &remain);
|
|
||||||
requested = &remain;
|
|
||||||
} while (ret != 0);
|
|
||||||
return ret;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +110,9 @@ u32 PS4_SYSV_ABI sceKernelSleep(u32 seconds) {
|
|||||||
#ifndef CLOCK_MONOTONIC_COARSE
|
#ifndef CLOCK_MONOTONIC_COARSE
|
||||||
#define CLOCK_MONOTONIC_COARSE 6
|
#define CLOCK_MONOTONIC_COARSE 6
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CLOCK_MONOTONIC_RAW
|
||||||
|
#define CLOCK_MONOTONIC_RAW 7
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DELTA_EPOCH_IN_100NS 116444736000000000ULL
|
#define DELTA_EPOCH_IN_100NS 116444736000000000ULL
|
||||||
|
|
||||||
@ -133,7 +132,7 @@ static s32 clock_gettime(u32 clock_id, struct timespec* ts) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case CLOCK_MONOTONIC:
|
case CLOCK_MONOTONIC:
|
||||||
case CLOCK_MONOTONIC_COARSE: {
|
case CLOCK_MONOTONIC_RAW: {
|
||||||
static LARGE_INTEGER pf = [] {
|
static LARGE_INTEGER pf = [] {
|
||||||
LARGE_INTEGER res{};
|
LARGE_INTEGER res{};
|
||||||
QueryPerformanceFrequency(&pf);
|
QueryPerformanceFrequency(&pf);
|
||||||
@ -158,7 +157,7 @@ static s32 clock_gettime(u32 clock_id, struct timespec* ts) {
|
|||||||
}
|
}
|
||||||
case CLOCK_THREAD_CPUTIME_ID: {
|
case CLOCK_THREAD_CPUTIME_ID: {
|
||||||
FILETIME ct, et, kt, ut;
|
FILETIME ct, et, kt, ut;
|
||||||
if (!GetThreadTimes(GetCurrentThread(), &ct, &et, &kt, &ut)) {
|
if (!GetThreadTimes(GetCurrentProcess(), &ct, &et, &kt, &ut)) {
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
}
|
}
|
||||||
const u64 ns = FileTimeTo100Ns(ut) + FileTimeTo100Ns(kt);
|
const u64 ns = FileTimeTo100Ns(ut) + FileTimeTo100Ns(kt);
|
||||||
@ -172,8 +171,8 @@ static s32 clock_gettime(u32 clock_id, struct timespec* ts) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, struct timespec* ts) {
|
int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, OrbisKernelTimespec* tp) {
|
||||||
if (ts == nullptr) {
|
if (tp == nullptr) {
|
||||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
return ORBIS_KERNEL_ERROR_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,12 +184,11 @@ int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, struct timespec* ts) {
|
|||||||
break;
|
break;
|
||||||
case ORBIS_CLOCK_SECOND:
|
case ORBIS_CLOCK_SECOND:
|
||||||
case ORBIS_CLOCK_REALTIME_FAST:
|
case ORBIS_CLOCK_REALTIME_FAST:
|
||||||
#ifndef __APPLE__
|
#ifdef __APPLE__
|
||||||
pclock_id = CLOCK_REALTIME_COARSE;
|
|
||||||
#else
|
|
||||||
pclock_id = CLOCK_REALTIME;
|
pclock_id = CLOCK_REALTIME;
|
||||||
#endif
|
#else
|
||||||
break;
|
pclock_id = CLOCK_REALTIME_COARSE;
|
||||||
|
#endif break;
|
||||||
case ORBIS_CLOCK_UPTIME:
|
case ORBIS_CLOCK_UPTIME:
|
||||||
case ORBIS_CLOCK_UPTIME_PRECISE:
|
case ORBIS_CLOCK_UPTIME_PRECISE:
|
||||||
case ORBIS_CLOCK_MONOTONIC:
|
case ORBIS_CLOCK_MONOTONIC:
|
||||||
@ -199,19 +197,15 @@ int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, struct timespec* ts) {
|
|||||||
break;
|
break;
|
||||||
case ORBIS_CLOCK_UPTIME_FAST:
|
case ORBIS_CLOCK_UPTIME_FAST:
|
||||||
case ORBIS_CLOCK_MONOTONIC_FAST:
|
case ORBIS_CLOCK_MONOTONIC_FAST:
|
||||||
#ifndef __APPLE__
|
pclock_id = CLOCK_MONOTONIC_RAW;
|
||||||
pclock_id = CLOCK_MONOTONIC_COARSE;
|
|
||||||
#else
|
|
||||||
pclock_id = CLOCK_MONOTONIC;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case ORBIS_CLOCK_THREAD_CPUTIME_ID:
|
case ORBIS_CLOCK_THREAD_CPUTIME_ID:
|
||||||
pclock_id = CLOCK_THREAD_CPUTIME_ID;
|
pclock_id = CLOCK_THREAD_CPUTIME_ID;
|
||||||
break;
|
break;
|
||||||
case ORBIS_CLOCK_PROCTIME: {
|
case ORBIS_CLOCK_PROCTIME: {
|
||||||
const auto us = sceKernelGetProcessTime();
|
const auto us = sceKernelGetProcessTime();
|
||||||
ts->tv_sec = us / 1'000'000;
|
tp->tv_sec = us / 1'000'000;
|
||||||
ts->tv_nsec = (us % 1'000'000) * 1000;
|
tp->tv_nsec = (us % 1'000'000) * 1000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ORBIS_CLOCK_VIRTUAL: {
|
case ORBIS_CLOCK_VIRTUAL: {
|
||||||
@ -221,16 +215,16 @@ int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, struct timespec* ts) {
|
|||||||
return EFAULT;
|
return EFAULT;
|
||||||
}
|
}
|
||||||
const u64 ns = FileTimeTo100Ns(ut);
|
const u64 ns = FileTimeTo100Ns(ut);
|
||||||
ts->tv_sec = ns / 10'000'000;
|
tp->tv_sec = ns / 10'000'000;
|
||||||
ts->tv_nsec = (ns % 10'000'000) * 100;
|
tp->tv_nsec = (ns % 10'000'000) * 100;
|
||||||
#else
|
#else
|
||||||
struct rusage ru;
|
struct rusage ru;
|
||||||
const auto res = getrusage(RUSAGE_SELF, &ru);
|
const auto res = getrusage(RUSAGE_SELF, &ru);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
ts->tv_sec = ru.ru_utime.tv_sec;
|
tp->tv_sec = ru.ru_utime.tv_sec;
|
||||||
ts->tv_nsec = ru.ru_utime.tv_usec * 1000;
|
tp->tv_nsec = ru.ru_utime.tv_usec * 1000;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -241,16 +235,16 @@ int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, struct timespec* ts) {
|
|||||||
return EFAULT;
|
return EFAULT;
|
||||||
}
|
}
|
||||||
const u64 ns = FileTimeTo100Ns(kt);
|
const u64 ns = FileTimeTo100Ns(kt);
|
||||||
ts->tv_sec = ns / 10'000'000;
|
tp->tv_sec = ns / 10'000'000;
|
||||||
ts->tv_nsec = (ns % 10'000'000) * 100;
|
tp->tv_nsec = (ns % 10'000'000) * 100;
|
||||||
#else
|
#else
|
||||||
struct rusage ru;
|
struct rusage ru;
|
||||||
const auto res = getrusage(RUSAGE_SELF, &ru);
|
const auto res = getrusage(RUSAGE_SELF, &ru);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
ts->tv_sec = ru.ru_stime.tv_sec;
|
tp->tv_sec = ru.ru_stime.tv_sec;
|
||||||
ts->tv_nsec = ru.ru_stime.tv_usec * 1000;
|
tp->tv_nsec = ru.ru_stime.tv_usec * 1000;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -265,17 +259,23 @@ int PS4_SYSV_ABI orbis_clock_gettime(s32 clock_id, struct timespec* ts) {
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clock_gettime(pclock_id, ts);
|
struct timespec ts;
|
||||||
|
const auto res = clock_gettime(pclock_id, &ts);
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp->tv_sec = ts.tv_sec;
|
||||||
|
tp->tv_nsec = ts.tv_nsec;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) {
|
int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) {
|
||||||
struct timespec ts;
|
const auto res = orbis_clock_gettime(clock_id, tp);
|
||||||
const auto res = orbis_clock_gettime(clock_id, &ts);
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return ErrnoToSceKernelError(res);
|
return ErrnoToSceKernelError(res);
|
||||||
}
|
}
|
||||||
tp->tv_sec = ts.tv_sec;
|
|
||||||
tp->tv_nsec = ts.tv_nsec;
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,4 +469,4 @@ void RegisterTime(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
Loading…
Reference in New Issue
Block a user