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
This commit is contained in:
parent
784ac71b15
commit
d17de81175
|
@ -404,17 +404,29 @@ case "$host_os" in
|
|||
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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -15,20 +15,62 @@
|
|||
#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).
|
||||
*
|
||||
* @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_get(void)
|
||||
ecore_time_unix_get(void)
|
||||
{
|
||||
#ifdef HAVE_EVIL
|
||||
return evil_time_get();
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue