mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04:00
coreinit: Time to tick conversion is unsigned
The result is treated as signed in most cases, but the calculation uses unsigned arithmetic. As a concrete example where this matters, DS VC passes -1 (2^64-1) to OSWaitEventWithTimeout which internally causes an overflow. But only with unsigned arithmetic this will result in a large positive number that behaves like the intended infinite timeout. With signed arithmetic the result is negative and the events will timeout immediately.
This commit is contained in:
parent
e834515f43
commit
c714e8cb6b
2 changed files with 5 additions and 7 deletions
|
@ -73,8 +73,6 @@ namespace coreinit
|
|||
}
|
||||
}
|
||||
|
||||
uint64 coreinit_getOSTime();
|
||||
|
||||
bool OSWaitEventWithTimeout(OSEvent* event, uint64 timeout)
|
||||
{
|
||||
__OSLockScheduler();
|
||||
|
@ -95,14 +93,14 @@ namespace coreinit
|
|||
|
||||
// workaround for a bad implementation in some Unity games (like Qube Directors Cut, see FEventWiiU::Wait)
|
||||
// where the the return value of OSWaitEventWithTimeout is ignored and instead the game measures the elapsed time to determine if a timeout occurred
|
||||
timeout = timeout * 98ULL / 100ULL; // 98% (we want the function to return slightly before the actual timeout)
|
||||
if (timeout < 0x00FFFFFFFFFFFFFFULL)
|
||||
timeout = timeout * 98ULL / 100ULL; // 98% (we want the function to return slightly before the actual timeout)
|
||||
|
||||
WaitEventWithTimeoutData data;
|
||||
data.thread = OSGetCurrentThread();
|
||||
data.threadQueue = &event->threadQueue;
|
||||
data.hasTimeout = false;
|
||||
|
||||
auto hostAlarm = coreinit::OSHostAlarmCreate(coreinit::coreinit_getOSTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout), 0, _OSWaitEventWithTimeoutHandler, &data);
|
||||
auto hostAlarm = coreinit::OSHostAlarmCreate(OSGetTime() + coreinit::EspressoTime::ConvertNsToTimerTicks(timeout), 0, _OSWaitEventWithTimeoutHandler, &data);
|
||||
event->threadQueue.queueAndWait(OSGetCurrentThread());
|
||||
coreinit::OSHostAlarmDestroy(hostAlarm);
|
||||
if (data.hasTimeout)
|
||||
|
|
|
@ -40,12 +40,12 @@ namespace coreinit
|
|||
|
||||
inline TimerTicks ConvertNsToTimerTicks(uint64 ns)
|
||||
{
|
||||
return ((GetTimerClock() / 31250LL) * ((TimerTicks)ns) / 32000LL);
|
||||
return static_cast<TimerTicks>((static_cast<uint64>(GetTimerClock()) / 31250ULL) * (ns) / 32000ULL);
|
||||
}
|
||||
|
||||
inline TimerTicks ConvertMsToTimerTicks(uint64 ms)
|
||||
{
|
||||
return (TimerTicks)ms * GetTimerClock() / 1000LL;
|
||||
return static_cast<TimerTicks>(ms * static_cast<uint64>(GetTimerClock()) / 1000ULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue