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

Reply via email to