FYI! Application and Library authors should review their usage of ecore_time_get()!
Efreet is a bad boy there, needs fixing! ---------- Forwarded message ---------- From: Enlightenment SVN <[email protected]> Date: Mon, Sep 27, 2010 at 7:35 PM Subject: E SVN: lucas IN trunk/ecore: . src/lib/ecore To: [email protected] Log: Make ecore_time_get and friends use monotonic clock Instead of relying on unix time, use a monotonic clock provided by clock_gettime(). If a monotonic clock is not available, it will fallback to CLOCK_REALTIME or unix time if neither is available. The impact is that now it only makes sense to call ecore_time_get() or ecore_time_loop_get() if the value retrieved is intended to be used as relative to previous/posterior measurements. If an absolute value is needed, the right function to call now is ecore_time_unix_get() which will give the number of seconds since Jan 1st, 1970, 12:00AM. Author: lucas Date: 2010-09-27 15:35:35 -0700 (Mon, 27 Sep 2010) New Revision: 52824 Modified: trunk/ecore/configure.ac trunk/ecore/src/lib/ecore/Ecore.h trunk/ecore/src/lib/ecore/Makefile.am trunk/ecore/src/lib/ecore/ecore.c trunk/ecore/src/lib/ecore/ecore_private.h trunk/ecore/src/lib/ecore/ecore_time.c Modified: trunk/ecore/configure.ac =================================================================== --- trunk/ecore/configure.ac 2010-09-27 22:34:25 UTC (rev 52823) +++ trunk/ecore/configure.ac 2010-09-27 22:35:35 UTC (rev 52824) @@ -404,18 +404,30 @@ mingw32ce* | cegcc*) WIN32_LIBS="-lws2" dlopen_libs="-ldl" + rt_libs="-lrt" ;; mingw*) WIN32_LIBS="-lws2_32" dlopen_libs="-ldl" + rt_libs="-lrt" ;; *) AC_CHECK_LIB(dl, dlopen, dlopen_libs=-ldl) + AC_CHECK_LIB(rt, clock_gettime, rt_libs=-lrt) ;; esac AC_SUBST(WIN32_LIBS) AC_SUBST(dlopen_libs) +AC_SUBST(rt_libs) +if test -n "$rt_libs"; then + _bkp_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $rt_libs" + AC_CHECK_FUNCS(clock_gettime) + LDFLAGS="$_bkp_LDFLAGS" + unset "$_bkp_LDFLAGS" +fi + # Eina library PKG_CHECK_MODULES(EINA, [eina >= 1.0.0]) Modified: trunk/ecore/src/lib/ecore/Ecore.h =================================================================== --- trunk/ecore/src/lib/ecore/Ecore.h 2010-09-27 22:34:25 UTC (rev 52823) +++ trunk/ecore/src/lib/ecore/Ecore.h 2010-09-27 22:35:35 UTC (rev 52824) @@ -445,6 +445,7 @@ EAPI double ecore_time_get(void); + EAPI double ecore_time_unix_get(void); EAPI double ecore_loop_time_get(void); EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); Modified: trunk/ecore/src/lib/ecore/Makefile.am =================================================================== --- trunk/ecore/src/lib/ecore/Makefile.am 2010-09-27 22:34:25 UTC (rev 52823) +++ trunk/ecore/src/lib/ecore/Makefile.am 2010-09-27 22:35:35 UTC (rev 52824) @@ -45,7 +45,7 @@ endif -libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ -lm +libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ EXTRA_DIST = ecore_private.h Modified: trunk/ecore/src/lib/ecore/ecore.c =================================================================== --- trunk/ecore/src/lib/ecore/ecore.c 2010-09-27 22:34:25 UTC (rev 52823) +++ trunk/ecore/src/lib/ecore/ecore.c 2010-09-27 22:35:35 UTC (rev 52824) @@ -117,7 +117,7 @@ _ecore_thread_init(); _ecore_glib_init(); _ecore_job_init(); - _ecore_loop_time = ecore_time_get(); + _ecore_time_init(); #if HAVE_MALLINFO if (getenv("ECORE_MEM_STAT")) Modified: trunk/ecore/src/lib/ecore/ecore_private.h =================================================================== --- trunk/ecore/src/lib/ecore/ecore_private.h 2010-09-27 22:34:25 UTC (rev 52823) +++ trunk/ecore/src/lib/ecore/ecore_private.h 2010-09-27 22:35:35 UTC (rev 52824) @@ -117,6 +117,8 @@ EAPI void _ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname); +void _ecore_time_init(void); + void _ecore_timer_shutdown(void); void _ecore_timer_cleanup(void); void _ecore_timer_enable_new(void); Modified: trunk/ecore/src/lib/ecore/ecore_time.c =================================================================== --- trunk/ecore/src/lib/ecore/ecore_time.c 2010-09-27 22:34:25 UTC (rev 52823) +++ trunk/ecore/src/lib/ecore/ecore_time.c 2010-09-27 22:35:35 UTC (rev 52824) @@ -15,21 +15,63 @@ #include "Ecore.h" #include "ecore_private.h" +#include <time.h> +#if HAVE_CLOCK_GETTIME +static clockid_t _ecore_time_clock_id = -1; +#endif +double _ecore_loop_time = -1.0; -/* FIXME: clock_gettime() is an option... */ - /** * Retrieves the current system time as a floating point value in seconds. * - * Also see ecore_loop_time_get(). + * This uses a monotonic clock and thus never goes back in time while + * machine is live (even if user changes time or timezone changes, + * however it may be reset whenever the machine is restarted). * - * @return The number of seconds since 12.00AM 1st January 1970. + * @see ecore_loop_time_get(). + * @see ecore_time_unix_get(). + * + * @return The number of seconds. Start time is not defined (it may be + * when the machine was booted, unix time, etc), all it is + * defined is that it never goes backwards (unless you got big critical + * messages when the application started). * @ingroup Ecore_Time_Group */ EAPI double ecore_time_get(void) { +#if !HAVE_CLOCK_GETTIME + return ecore_time_unix_get(); +#else + struct timespec t; + + if (EINA_UNLIKELY(_ecore_time_clock_id < 0)) + return ecore_time_unix_get(); + + if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t))) + { + CRIT("Cannot get current time."); + /* Try to at least return the latest value retrieved*/ + return _ecore_loop_time; + } + + return (double)t.tv_sec + (((double)t.tv_nsec) / 1000000000.0); +#endif +} + +/** + * Retrieves the current UNIX time as a floating point value in seconds. + * + * @see ecore_time_get(). + * @see ecore_loop_time_get(). + * + * @return The number of seconds since 12.00AM 1st January 1970. + * @ingroup Ecore_Time_Group + */ +EAPI double +ecore_time_unix_get(void) +{ #ifdef HAVE_EVIL return evil_time_get(); #else @@ -44,21 +86,26 @@ #endif } -double _ecore_loop_time = -1.0; - /** - * Retrieves the time at which the last loop stopped waiting for timeouts or events + * Retrieves the time at which the last loop stopped waiting for timeouts or + * events. * - * This gets the time (since Jan 1st, 1970, 12:00AM) that the main loop ceased - * waiting for timouts and/or events to come in or for signals or any other - * interrupt source. This should be considered a reference point for all - * time based activity that should calculate its timepoint from the return - * of ecore_loop_time_get(). use this UNLESS you absolutely must get the - * current actual timepoint - then use ecore_time_get(). If this is called - * before any loop has ever been run, then it will call ecore_time_get() for - * you the first time and thus have an initial time reference. + * This gets the time that the main loop ceased waiting for timouts and/or + * events to come in or for signals or any other interrupt source. This should + * be considered a reference point for all time based activity that should + * calculate its timepoint from the return of ecore_loop_time_get(). Use this + * UNLESS you absolutely must get the current actual timepoint - then use + * ecore_time_get(). Note that this time is meant to be used as relative to + * other times obtained on this run. If you need absolute time references, use + * ecore_time_unix_get() instead. * - * @return The number of seconds since 12.00AM 1st January 1970. + * This function can be called before any loop has ever been run, but either + * ecore_init() or ecore_time_get() must have been called once. + * + * @return The number of seconds. Start time is not defined (it may be + * when the machine was booted, unix time, etc), all it is + * defined is that it never goes backwards (unless you got big critical + * messages when the application started). * @ingroup Ecore_Time_Group */ EAPI double @@ -66,3 +113,45 @@ { return _ecore_loop_time; } + + +/********************** Internal methods ********************************/ + +/* TODO: Documentation says "All implementations support the system-wide + * real-time clock, which is identified by CLOCK_REALTIME. Check if the fallback + * to unix time (without specifying the resolution) might be removed + */ +void +_ecore_time_init(void) +{ +#if HAVE_CLOCK_GETTIME + struct timespec t; + + if (_ecore_time_clock_id != -1) return; + + if (!clock_gettime(CLOCK_MONOTONIC, &t)) + { + _ecore_time_clock_id = CLOCK_MONOTONIC; + DBG("using CLOCK_MONOTONIC."); + } + else if (!clock_gettime(CLOCK_REALTIME, &t)) + { + /* may go backwards */ + _ecore_time_clock_id = CLOCK_REALTIME; + WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME."); + } + else + { + _ecore_time_clock_id = -2; + CRIT("Cannot get a valid clock_gettime() clock id! " + "Fallback to unix time."); + } +#else +# warning "Your platform isn't supported yet" + _ecore_time_clock_it = -2; + CRIT("Platform does not support clock_gettime. " + "Fallback to unix time."); +#endif + + _ecore_loop_time = ecore_time_get(); +} ------------------------------------------------------------------------------ Start uncovering the many advantages of virtual appliances and start using them to simplify application deployment and accelerate your shift to cloud computing. http://p.sf.net/sfu/novell-sfdev2dev _______________________________________________ enlightenment-svn mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-svn -- Gustavo Sverzut Barbieri http://profusion.mobi embedded systems -------------------------------------- MSN: [email protected] Skype: gsbarbieri Mobile: +55 (19) 9225-2202 ------------------------------------------------------------------------------ Start uncovering the many advantages of virtual appliances and start using them to simplify application deployment and accelerate your shift to cloud computing. http://p.sf.net/sfu/novell-sfdev2dev _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
