mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Fix system time wraparound
Implement utils::udiv128, utils::div128
This commit is contained in:
parent
7f99de36c1
commit
81a110f346
2 changed files with 60 additions and 3 deletions
|
@ -174,6 +174,32 @@ namespace utils
|
|||
return (x * y) >> 64;
|
||||
}
|
||||
|
||||
constexpr s64 div128(s64 high, s64 low, s64 divisor, s64* remainder = nullptr)
|
||||
{
|
||||
const __int128_t x = (__uint128_t{u64(high)} << 64) | u64(low);
|
||||
const __int128_t r = x / divisor;
|
||||
|
||||
if (remainder)
|
||||
{
|
||||
*remainder = x % divisor;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
constexpr u64 udiv128(u64 high, u64 low, u64 divisor, u64* remainder = nullptr)
|
||||
{
|
||||
const __uint128_t x = (__uint128_t{high} << 64) | low;
|
||||
const __uint128_t r = x / divisor;
|
||||
|
||||
if (remainder)
|
||||
{
|
||||
*remainder = x % divisor;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
inline u8 rol8(u8 x, u8 n)
|
||||
{
|
||||
|
@ -224,5 +250,31 @@ namespace utils
|
|||
{
|
||||
return __mulh(x, y);
|
||||
}
|
||||
|
||||
inline s64 div128(s64 high, s64 low, s64 divisor, s64* remainder = nullptr)
|
||||
{
|
||||
s64 rem;
|
||||
s64 r = _div128(high, low, divisor, &rem);
|
||||
|
||||
if (remainder)
|
||||
{
|
||||
*remainder = rem;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline u64 udiv128(u64 high, u64 low, u64 divisor, u64* remainder = nullptr)
|
||||
{
|
||||
u64 rem;
|
||||
u64 r = _udiv128(high, low, divisor, &rem);
|
||||
|
||||
if (remainder)
|
||||
{
|
||||
*remainder = rem;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
} // namespace utils
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
#include "Utilities/asm.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
|
@ -196,8 +197,12 @@ s32 sys_time_get_current_time(vm::ptr<s64> sec, vm::ptr<s64> nsec)
|
|||
LARGE_INTEGER count;
|
||||
verify(HERE), QueryPerformanceCounter(&count);
|
||||
|
||||
// get time difference in nanoseconds
|
||||
const u64 diff = (count.QuadPart - s_time_aux_info.start_time) * 1000000000ull / s_time_aux_info.perf_freq;
|
||||
const u64 diff_base = count.QuadPart - s_time_aux_info.start_time;
|
||||
|
||||
// Get time difference in nanoseconds (using 128 bit accumulator)
|
||||
const u64 diff_sl = diff_base * 1000000000ull;
|
||||
const u64 diff_sh = utils::umulh64(diff_base, 1000000000ull);
|
||||
const u64 diff = utils::udiv128(diff_sh, diff_sl, s_time_aux_info.perf_freq);
|
||||
|
||||
// get time since Epoch in nanoseconds
|
||||
const u64 time = s_time_aux_info.start_ftime * 100u + (diff * g_cfg.core.clocks_scale / 100u);
|
||||
|
@ -237,7 +242,7 @@ s32 sys_time_get_current_time(vm::ptr<s64> sec, vm::ptr<s64> nsec)
|
|||
{
|
||||
// Correct value if borrow encountered
|
||||
tv_sec -= 1;
|
||||
tv_nsec = 1'000'000'000ull - (stv_nsec - tv_nsec);
|
||||
tv_nsec = 1'000'000'000ull - (stv_nsec - tv_nsec);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue