aboutsummaryrefslogtreecommitdiffstats
path: root/legacy/ecore/src/lib
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.demarchi@profusion.mobi>2010-09-27 22:35:35 +0000
committerLucas De Marchi <lucas.demarchi@profusion.mobi>2010-09-27 22:35:35 +0000
commitd17de811757c09c89b64631d442884bb14791c57 (patch)
tree25592ef8fb3277d58ffd9c428ab1ccd531db8765 /legacy/ecore/src/lib
parentDon't screw up script {} highlighting when there are several levels of {} (diff)
downloadefl-d17de811757c09c89b64631d442884bb14791c57.tar.gz
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. SVN revision: 52824
Diffstat (limited to 'legacy/ecore/src/lib')
-rw-r--r--legacy/ecore/src/lib/ecore/Ecore.h1
-rw-r--r--legacy/ecore/src/lib/ecore/Makefile.am2
-rw-r--r--legacy/ecore/src/lib/ecore/ecore.c2
-rw-r--r--legacy/ecore/src/lib/ecore/ecore_private.h2
-rw-r--r--legacy/ecore/src/lib/ecore/ecore_time.c121
5 files changed, 110 insertions, 18 deletions
diff --git a/legacy/ecore/src/lib/ecore/Ecore.h b/legacy/ecore/src/lib/ecore/Ecore.h
index d3645e9c15..f547f5e47e 100644
--- a/legacy/ecore/src/lib/ecore/Ecore.h
+++ b/legacy/ecore/src/lib/ecore/Ecore.h
@@ -445,6 +445,7 @@ extern "C" {
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);
diff --git a/legacy/ecore/src/lib/ecore/Makefile.am b/legacy/ecore/src/lib/ecore/Makefile.am
index 960e9dc816..37e7bda5b2 100644
--- a/legacy/ecore/src/lib/ecore/Makefile.am
+++ b/legacy/ecore/src/lib/ecore/Makefile.am
@@ -45,7 +45,7 @@ endif
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
diff --git a/legacy/ecore/src/lib/ecore/ecore.c b/legacy/ecore/src/lib/ecore/ecore.c
index 5bf12bc10d..8f2a045f72 100644
--- a/legacy/ecore/src/lib/ecore/ecore.c
+++ b/legacy/ecore/src/lib/ecore/ecore.c
@@ -117,7 +117,7 @@ ecore_init(void)
_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"))
diff --git a/legacy/ecore/src/lib/ecore/ecore_private.h b/legacy/ecore/src/lib/ecore/ecore_private.h
index 170845941b..5ff4ab27d3 100644
--- a/legacy/ecore/src/lib/ecore/ecore_private.h
+++ b/legacy/ecore/src/lib/ecore/ecore_private.h
@@ -117,6 +117,8 @@ typedef unsigned int Ecore_Magic;
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);
diff --git a/legacy/ecore/src/lib/ecore/ecore_time.c b/legacy/ecore/src/lib/ecore/ecore_time.c
index 9e51df6abf..b26a390eee 100644
--- a/legacy/ecore/src/lib/ecore/ecore_time.c
+++ b/legacy/ecore/src/lib/ecore/ecore_time.c
@@ -15,21 +15,63 @@
#include "Ecore.h"
#include "ecore_private.h"
+#include <time.h>
-
-/* FIXME: clock_gettime() is an option... */
+#if HAVE_CLOCK_GETTIME
+static clockid_t _ecore_time_clock_id = -1;
+#endif
+double _ecore_loop_time = -1.0;
/**
* 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 @@ ecore_time_get(void)
#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 @@ ecore_loop_time_get(void)
{
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();
+}