1 #ifdef HAVE_CONFIG_H 2 # include <config.h> 3 #endif 4 5 #define EFL_LOOP_PROTECTED 6 7 #include <stdlib.h> 8 #include <sys/time.h> 9 10 #if defined(__APPLE__) && defined(__MACH__) 11 # include <mach/mach_time.h> 12 #endif 13 14 #include <time.h> 15 16 #ifdef _WIN32 17 # include <evil_private.h> /* gettimeofday */ 18 #endif 19 20 #include "Ecore.h" 21 #include "ecore_private.h" 22 23 #if defined(_WIN32) 24 static LONGLONG _ecore_time_freq; 25 #elif defined (HAVE_CLOCK_GETTIME) 26 static clockid_t _ecore_time_clock_id; 27 static Eina_Bool _ecore_time_got_clock_id = EINA_FALSE; 28 #elif defined(__APPLE__) && defined(__MACH__) 29 static double _ecore_time_clock_conversion = 1e-9; 30 #endif 31 32 EAPI double ecore_time_get(void)33ecore_time_get(void) 34 { 35 #ifdef _WIN32 36 LARGE_INTEGER count; 37 38 QueryPerformanceCounter(&count); 39 return (double)count.QuadPart/ (double)_ecore_time_freq; 40 #elif defined (HAVE_CLOCK_GETTIME) 41 struct timespec t; 42 43 if (EINA_UNLIKELY(!_ecore_time_got_clock_id)) 44 return ecore_time_unix_get(); 45 46 if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t))) 47 { 48 CRI("Cannot get current time"); 49 return 0.0; 50 } 51 52 return (double)t.tv_sec + (((double)t.tv_nsec) / 1000000000.0); 53 #elif defined(__APPLE__) && defined(__MACH__) 54 return _ecore_time_clock_conversion * (double)mach_absolute_time(); 55 #else 56 return ecore_time_unix_get(); 57 #endif 58 } 59 60 EAPI double ecore_time_unix_get(void)61ecore_time_unix_get(void) 62 { 63 #ifdef HAVE_GETTIMEOFDAY 64 struct timeval timev; 65 66 gettimeofday(&timev, NULL); 67 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); 68 #else 69 # error "Your platform isn't supported yet" 70 #endif 71 } 72 73 EAPI double ecore_loop_time_get(void)74ecore_loop_time_get(void) 75 { 76 return efl_loop_time_get(ML_OBJ); 77 } 78 79 EAPI void ecore_loop_time_set(double t)80ecore_loop_time_set(double t) 81 { 82 efl_loop_time_set(ML_OBJ, t); 83 } 84 85 /*-******************** Internal methods ********************************/ 86 87 /* TODO: Documentation says "All implementations support the system-wide 88 * real-time clock, which is identified by CLOCK_REALTIME. Check if the fallback 89 * to unix time (without specifying the resolution) might be removed 90 */ 91 void _ecore_time_init(void)92_ecore_time_init(void) 93 { 94 #if defined(_WIN32) 95 LARGE_INTEGER freq; 96 97 QueryPerformanceFrequency(&freq); 98 _ecore_time_freq = freq.QuadPart; 99 #elif defined(HAVE_CLOCK_GETTIME) 100 struct timespec t; 101 102 if (_ecore_time_got_clock_id) return; 103 104 if (!clock_gettime(CLOCK_MONOTONIC, &t)) 105 { 106 _ecore_time_clock_id = CLOCK_MONOTONIC; 107 _ecore_time_got_clock_id = EINA_TRUE; 108 DBG("using CLOCK_MONOTONIC"); 109 } 110 else if (!clock_gettime(CLOCK_REALTIME, &t)) 111 { 112 // may go backwards 113 _ecore_time_clock_id = CLOCK_REALTIME; 114 _ecore_time_got_clock_id = EINA_TRUE; 115 WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME"); 116 } 117 else 118 CRI("Cannot get a valid clock_gettime() clock id! Fallback to unix time"); 119 #else 120 # if defined(__APPLE__) && defined(__MACH__) 121 mach_timebase_info_data_t info; 122 kern_return_t err = mach_timebase_info(&info); 123 if (err == 0) 124 _ecore_time_clock_conversion = 1e-9 * (double)info.numer / (double)info.denom; 125 else 126 WRN("Unable to get timebase info. Fallback to nanoseconds"); 127 # else 128 # warning "Your platform isn't supported yet" 129 CRI("Platform does not support clock_gettime. Fallback to unix time"); 130 # endif 131 #endif 132 ecore_loop_time_set(ecore_time_get()); 133 } 134 135