Use monotonic clock for get_ticks_usec

Static _clock_start and _clock_setup function.
Use clock_gettime on Unix, mach_absolute_time on Mac.
This commit is contained in:
Fabio Alessandrelli 2018-09-25 13:40:53 +02:00
parent c6f09fb97b
commit 460e3376a4
2 changed files with 38 additions and 9 deletions

View File

@ -45,6 +45,7 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#include <mach/mach_time.h>
#endif #endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) #if defined(__FreeBSD__) || defined(__OpenBSD__)
@ -64,6 +65,32 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
/// Clock Setup function (used by get_ticks_usec)
static uint64_t _clock_start = 0;
#if defined(__APPLE__)
static double _clock_scale = 0;
static void _setup_clock() {
mach_timebase_info_data_t info;
kern_return_t ret = mach_timebase_info(&info);
ERR_EXPLAIN("OS CLOCK IS NOT WORKING!");
ERR_FAIL_COND(ret != 0);
_clock_scale = (double)info.numer / (double)info.denom;
_clock_start = mach_absolute_time() * _clock_scale;
}
#else
#if defined(CLOCK_MONOTONIC_RAW) && !defined(JAVASCRIPT_ENABLED) // This is a better clock on Linux.
#define GODOT_CLOCK CLOCK_MONOTONIC_RAW
#else
#define GODOT_CLOCK CLOCK_MONOTONIC
#endif
static void _setup_clock() {
struct timespec tv_now = { 0, 0 };
ERR_EXPLAIN("OS CLOCK IS NOT WORKING!");
ERR_FAIL_COND(clock_gettime(GODOT_CLOCK, &tv_now) != 0);
_clock_start = ((uint64_t)tv_now.tv_nsec / 1000L) + (uint64_t)tv_now.tv_sec * 1000000L;
}
#endif
void OS_Unix::debug_break() { void OS_Unix::debug_break() {
assert(false); assert(false);
@ -126,8 +153,7 @@ void OS_Unix::initialize_core() {
IP_Unix::make_default(); IP_Unix::make_default();
#endif #endif
ticks_start = 0; _setup_clock();
ticks_start = get_ticks_usec();
struct sigaction sa; struct sigaction sa;
sa.sa_handler = &handle_sigchld; sa.sa_handler = &handle_sigchld;
@ -246,11 +272,16 @@ void OS_Unix::delay_usec(uint32_t p_usec) const {
} }
uint64_t OS_Unix::get_ticks_usec() const { uint64_t OS_Unix::get_ticks_usec() const {
struct timeval tv_now; #if defined(__APPLE__)
gettimeofday(&tv_now, NULL); uint64_t longtime = mach_absolute_time() * _clock_scale;
#else
uint64_t longtime = (uint64_t)tv_now.tv_usec + (uint64_t)tv_now.tv_sec * 1000000L; // Unchecked return. Static analyzers might complain.
longtime -= ticks_start; // If _setup_clock() succeded, we assume clock_gettime() works.
struct timespec tv_now = { 0, 0 };
clock_gettime(GODOT_CLOCK, &tv_now);
uint64_t longtime = ((uint64_t)tv_now.tv_nsec / 1000L) + (uint64_t)tv_now.tv_sec * 1000000L;
#endif
longtime -= _clock_start;
return longtime; return longtime;
} }

View File

@ -42,8 +42,6 @@
class OS_Unix : public OS { class OS_Unix : public OS {
uint64_t ticks_start;
protected: protected:
// UNIX only handles the core functions. // UNIX only handles the core functions.
// inheriting platforms under unix (eg. X11) should handle the rest // inheriting platforms under unix (eg. X11) should handle the rest