mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-16 09:02:06 +00:00
Use nanosleep for I_SleepDuration on *nix
This commit is contained in:
parent
a68440c4db
commit
b98d9dfe52
2 changed files with 46 additions and 35 deletions
35
src/i_time.c
35
src/i_time.c
|
@ -88,38 +88,3 @@ void I_UpdateTime(fixed_t timescale)
|
||||||
g_time.timefrac = FLOAT_TO_FIXED(fractional);
|
g_time.timefrac = FLOAT_TO_FIXED(fractional);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_SleepDuration(precise_t duration)
|
|
||||||
{
|
|
||||||
UINT64 precision = I_GetPrecisePrecision();
|
|
||||||
INT32 sleepvalue = cv_sleep.value;
|
|
||||||
UINT64 delaygranularity;
|
|
||||||
precise_t cur;
|
|
||||||
precise_t dest;
|
|
||||||
|
|
||||||
{
|
|
||||||
double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS));
|
|
||||||
delaygranularity = (UINT64)gran;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = I_GetPreciseTime();
|
|
||||||
dest = cur + duration;
|
|
||||||
|
|
||||||
// the reason this is not dest > cur is because the precise counter may wrap
|
|
||||||
// two's complement arithmetic is our friend here, though!
|
|
||||||
// e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1
|
|
||||||
// 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3
|
|
||||||
while ((INT64)(dest - cur) > 0)
|
|
||||||
{
|
|
||||||
// If our cv_sleep value exceeds the remaining sleep duration, use the
|
|
||||||
// hard sleep function.
|
|
||||||
if (sleepvalue > 0 && (dest - cur) > delaygranularity)
|
|
||||||
{
|
|
||||||
I_Sleep(sleepvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, this is a spinloop.
|
|
||||||
|
|
||||||
cur = I_GetPreciseTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2265,6 +2265,52 @@ void I_Sleep(UINT32 ms)
|
||||||
SDL_Delay(ms);
|
SDL_Delay(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_SleepDuration(precise_t duration)
|
||||||
|
{
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
UINT64 precision = I_GetPrecisePrecision();
|
||||||
|
struct timespec ts = {
|
||||||
|
.tv_sec = duration / precision,
|
||||||
|
.tv_nsec = duration * 1000000000 / precision % 1000000000,
|
||||||
|
};
|
||||||
|
int status;
|
||||||
|
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
|
||||||
|
while (status == EINTR);
|
||||||
|
#else
|
||||||
|
UINT64 precision = I_GetPrecisePrecision();
|
||||||
|
INT32 sleepvalue = cv_sleep.value;
|
||||||
|
UINT64 delaygranularity;
|
||||||
|
precise_t cur;
|
||||||
|
precise_t dest;
|
||||||
|
|
||||||
|
{
|
||||||
|
double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS));
|
||||||
|
delaygranularity = (UINT64)gran;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = I_GetPreciseTime();
|
||||||
|
dest = cur + duration;
|
||||||
|
|
||||||
|
// the reason this is not dest > cur is because the precise counter may wrap
|
||||||
|
// two's complement arithmetic is our friend here, though!
|
||||||
|
// e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1
|
||||||
|
// 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3
|
||||||
|
while ((INT64)(dest - cur) > 0)
|
||||||
|
{
|
||||||
|
// If our cv_sleep value exceeds the remaining sleep duration, use the
|
||||||
|
// hard sleep function.
|
||||||
|
if (sleepvalue > 0 && (dest - cur) > delaygranularity)
|
||||||
|
{
|
||||||
|
I_Sleep(sleepvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, this is a spinloop.
|
||||||
|
|
||||||
|
cur = I_GetPreciseTime();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NEWSIGNALHANDLER
|
#ifdef NEWSIGNALHANDLER
|
||||||
ATTRNORETURN static FUNCNORETURN void newsignalhandler_Warn(const char *pr)
|
ATTRNORETURN static FUNCNORETURN void newsignalhandler_Warn(const char *pr)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue