Ver código fonte

Use monotonic clock for get_ticks_usec

Static _clock_start and _clock_setup function.
Use clock_gettime on Unix, mach_absolute_time on Mac.
Fabio Alessandrelli 7 anos atrás
pai
commit
460e3376a4
2 arquivos alterados com 38 adições e 9 exclusões
  1. 38 7
      drivers/unix/os_unix.cpp
  2. 0 2
      drivers/unix/os_unix.h

+ 38 - 7
drivers/unix/os_unix.cpp

@@ -45,6 +45,7 @@
 
 #ifdef __APPLE__
 #include <mach-o/dyld.h>
+#include <mach/mach_time.h>
 #endif
 
 #if defined(__FreeBSD__) || defined(__OpenBSD__)
@@ -64,6 +65,32 @@
 #include <sys/wait.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() {
 
 	assert(false);
@@ -126,8 +153,7 @@ void OS_Unix::initialize_core() {
 	IP_Unix::make_default();
 #endif
 
-	ticks_start = 0;
-	ticks_start = get_ticks_usec();
+	_setup_clock();
 
 	struct sigaction sa;
 	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 {
 
-	struct timeval tv_now;
-	gettimeofday(&tv_now, NULL);
-
-	uint64_t longtime = (uint64_t)tv_now.tv_usec + (uint64_t)tv_now.tv_sec * 1000000L;
-	longtime -= ticks_start;
+#if defined(__APPLE__)
+	uint64_t longtime = mach_absolute_time() * _clock_scale;
+#else
+	// Unchecked return. Static analyzers might complain.
+	// 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;
 }

+ 0 - 2
drivers/unix/os_unix.h

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