mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Clocksource: use a better clock if available.
clock_gettime() is a far better clock than gettimeofday(). Even better than clock_gettime() is that you can select either CLOCK_MONOTONIC, or even CLOCK_MONOTONIC_RAW. These clocks offer high precision time. And the _RAW variant will never roll back due to NTP drift or daylight savings, or otherwise. I've adjusted this code to select the right clock method auto- matically based on what's available in the OS. This means that if you're running a very old linux version, MacOS or other, you will automatically get the best clocksource available. I've tested all Linux clocksources by selectively compiling and running a 10k+ timer test suite. In all cases I confirmed that the 3 POSIX Linux clocksources worked properly, and were selected properly. I've modified the OS X compile path to use the high-res clock source for all time functions, but I can't confirm it works or that it compiles. As for WIN32, I confirmed that the used clocksource is indeed a Monotonic clocksource, so good news: that code section appears to be exactly what it should be.
This commit is contained in:
parent
860d70bd0e
commit
4ac1e9bccb
@ -1727,7 +1727,7 @@ Helper functions
|
||||
* `minetest.is_yes(arg)`
|
||||
* returns whether `arg` can be interpreted as yes
|
||||
* `minetest.get_us_time()`
|
||||
* returns time with microsecond precision
|
||||
* returns time with microsecond precision. May not return wall time.
|
||||
* `table.copy(table)`: returns a table
|
||||
* returns a deep copy of `table`
|
||||
|
||||
|
@ -211,33 +211,11 @@ void initIrrlicht(irr::IrrlichtDevice * );
|
||||
}
|
||||
|
||||
#else // Posix
|
||||
|
||||
inline u32 getTimeS()
|
||||
inline void _os_get_clock(struct timespec *ts)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
inline u32 getTimeMs()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
inline u32 getTimeUs()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
}
|
||||
|
||||
inline u32 getTimeNs()
|
||||
{
|
||||
struct timespec ts;
|
||||
// from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
|
||||
#if defined(__MACH__) && defined(__APPLE__) // OS X does not have clock_gettime, use clock_get_time
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
// from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
|
||||
// OS X does not have clock_gettime, use clock_get_time
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t mts;
|
||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
|
||||
@ -245,9 +223,44 @@ void initIrrlicht(irr::IrrlichtDevice * );
|
||||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
ts.tv_sec = mts.tv_sec;
|
||||
ts.tv_nsec = mts.tv_nsec;
|
||||
#elif defined(CLOCK_MONOTONIC_RAW)
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, ts);
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK)
|
||||
clock_gettime(CLOCK_MONOTONIC, ts);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#endif
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
TIMEVAL_TO_TIMESPEC(&tv, ts);
|
||||
#endif // defined(__MACH__) && defined(__APPLE__)
|
||||
}
|
||||
|
||||
// Note: these clock functions do not return wall time, but
|
||||
// generally a clock that starts at 0 when the process starts.
|
||||
inline u32 getTimeS()
|
||||
{
|
||||
struct timespec ts;
|
||||
_os_get_clock(&ts);
|
||||
return ts.tv_sec;
|
||||
}
|
||||
|
||||
inline u32 getTimeMs()
|
||||
{
|
||||
struct timespec ts;
|
||||
_os_get_clock(&ts);
|
||||
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
inline u32 getTimeUs()
|
||||
{
|
||||
struct timespec ts;
|
||||
_os_get_clock(&ts);
|
||||
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
inline u32 getTimeNs()
|
||||
{
|
||||
struct timespec ts;
|
||||
_os_get_clock(&ts);
|
||||
return ts.tv_sec * 1000000000 + ts.tv_nsec;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user