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)`
|
* `minetest.is_yes(arg)`
|
||||||
* returns whether `arg` can be interpreted as yes
|
* returns whether `arg` can be interpreted as yes
|
||||||
* `minetest.get_us_time()`
|
* `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
|
* `table.copy(table)`: returns a table
|
||||||
* returns a deep copy of `table`
|
* returns a deep copy of `table`
|
||||||
|
|
||||||
|
@ -211,33 +211,11 @@ void initIrrlicht(irr::IrrlichtDevice * );
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else // Posix
|
#else // Posix
|
||||||
|
inline void _os_get_clock(struct timespec *ts)
|
||||||
inline u32 getTimeS()
|
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
#if defined(__MACH__) && defined(__APPLE__)
|
||||||
gettimeofday(&tv, NULL);
|
// from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
|
||||||
return tv.tv_sec;
|
// OS X does not have clock_gettime, use clock_get_time
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
clock_serv_t cclock;
|
clock_serv_t cclock;
|
||||||
mach_timespec_t mts;
|
mach_timespec_t mts;
|
||||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
|
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);
|
mach_port_deallocate(mach_task_self(), cclock);
|
||||||
ts.tv_sec = mts.tv_sec;
|
ts.tv_sec = mts.tv_sec;
|
||||||
ts.tv_nsec = mts.tv_nsec;
|
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
|
#else
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
struct timeval tv;
|
||||||
#endif
|
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;
|
return ts.tv_sec * 1000000000 + ts.tv_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user