diff --git a/legacy/ecore/ChangeLog b/legacy/ecore/ChangeLog index b26b72f533..e252db3e22 100644 --- a/legacy/ecore/ChangeLog +++ b/legacy/ecore/ChangeLog @@ -182,3 +182,7 @@ * Make ecore_con work on Windows (only the local connections need a port) * Make ecore_ipc compile on Windows + +2011-05-17 Cedric Bail + + * Add ecore_timer_dump. diff --git a/legacy/ecore/configure.ac b/legacy/ecore/configure.ac index d6c39dc0fc..07fa7cb667 100644 --- a/legacy/ecore/configure.ac +++ b/legacy/ecore/configure.ac @@ -344,6 +344,16 @@ else fi AC_SUBST(pkgconfig_requires_private) +### Checks for some build time option +want_ecore_timer_dump="yes" + +AC_ARG_ENABLE([ecore-timer-dump], + [AC_HELP_STRING([--disable-ecore-timer-dump], [disable tracking of timer allocation. @<:@default=enable@:>@])], + [want_ecore_timer_dump=$enableval], []) + +if test "x$want_ecore_timer_dump" = "xyes"; then + AC_DEFINE(WANT_ECORE_TIMER_DUMP, [1], [Want Ecore_Timer dump infrastructure]) +fi ### Checks for libraries @@ -1469,6 +1479,7 @@ echo " GLib support...............: $have_glib" echo " Always integrate GLib......: $want_glib_integration_always" echo " Use g_main_loop............: $want_g_main_loop" echo " Gathering memory statistic.: $have_mallinfo" +echo " Gathering timer allocation.: $want_ecore_timer_dump" echo " Ecore_Con....................: $have_ecore_con" if test "x$have_ecore_con" = "xyes" ; then echo $ECHO_N " OpenSSL....................: $have_openssl $ECHO_C" diff --git a/legacy/ecore/src/lib/ecore/Ecore.h b/legacy/ecore/src/lib/ecore/Ecore.h index c39b292841..5d826d1b1c 100644 --- a/legacy/ecore/src/lib/ecore/Ecore.h +++ b/legacy/ecore/src/lib/ecore/Ecore.h @@ -570,6 +570,7 @@ extern "C" { EAPI double ecore_timer_pending_get(Ecore_Timer *timer); EAPI double ecore_timer_precision_get(void); EAPI void ecore_timer_precision_set(double precision); + EAPI char *ecore_timer_dump(void); /** * @} diff --git a/legacy/ecore/src/lib/ecore/ecore_timer.c b/legacy/ecore/src/lib/ecore/ecore_timer.c index 606ccb5118..dadcf405ed 100644 --- a/legacy/ecore/src/lib/ecore/ecore_timer.c +++ b/legacy/ecore/src/lib/ecore/ecore_timer.c @@ -8,6 +8,12 @@ #include "Ecore.h" #include "ecore_private.h" +#ifdef WANT_ECORE_TIMER_DUMP +# include +# include +# define ECORE_TIMER_DEBUG_BT_NUM 64 + typedef void (*Ecore_Timer_Bt_Func) (); +#endif struct _Ecore_Timer { @@ -19,6 +25,11 @@ struct _Ecore_Timer Ecore_Task_Cb func; void *data; +#ifdef WANT_ECORE_TIMER_DUMP + Ecore_Timer_Bt_Func timer_bt[ECORE_TIMER_DEBUG_BT_NUM]; + int timer_bt_num; +#endif + int references; unsigned char delete_me : 1; unsigned char just_added : 1; @@ -27,6 +38,7 @@ struct _Ecore_Timer static void _ecore_timer_set(Ecore_Timer *timer, double at, double in, Ecore_Task_Cb func, void *data); +static int _ecore_timer_cmp(const void *d1, const void *d2); static int timers_added = 0; static int timers_delete_me = 0; @@ -129,6 +141,12 @@ ecore_timer_add(double in, Ecore_Task_Cb func, const void *data) if (!timer) return NULL; ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER); now = ecore_time_get(); + +#ifdef WANT_ECORE_TIMER_DUMP + timer->timer_bt_num = backtrace((void**) (timer->timer_bt), + ECORE_TIMER_DEBUG_BT_NUM); +#endif + _ecore_timer_set(timer, now + in, in, func, (void *)data); return timer; } @@ -342,6 +360,51 @@ ecore_timer_thaw(Ecore_Timer *timer) _ecore_timer_set(timer, timer->pending + now, timer->in, timer->func, timer->data); } +EAPI char * +ecore_timer_dump(void) +{ +#ifdef WANT_ECORE_TIMER_DUMP + Eina_Strbuf *result; + char *out; + Ecore_Timer *tm; + Eina_List *tmp = NULL; + + result = eina_strbuf_new(); + + EINA_INLIST_FOREACH(timers, tm) + tmp = eina_list_sorted_insert(tmp, _ecore_timer_cmp, tm); + + EINA_LIST_FREE(tmp, tm) + { + char **strings; + int nptrs; + int j; + + nptrs = backtrace((void**) tm->timer_bt, ECORE_TIMER_DEBUG_BT_NUM); + strings = backtrace_symbols((void**) tm->timer_bt, nptrs); + if (strings == NULL) + continue ; + + eina_strbuf_append_printf(result, "*** timer: %f ***\n", tm->in); + if (tm->frozen) + eina_strbuf_append(result, "FROZEN\n"); + if (tm->delete_me) + eina_strbuf_append(result, "DELETED\n"); + for (j = 0; j < nptrs; j++) + eina_strbuf_append_printf(result, "%s\n", strings[j]); + + free(strings); + } + + out = eina_strbuf_string_steal(result); + eina_strbuf_free(result); + + return out; +#else + return NULL; +#endif +} + /** * @} */ @@ -601,3 +664,12 @@ _ecore_timer_set(Ecore_Timer *timer, double at, double in, Ecore_Task_Cb func, v } timers = (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); } + +static int +_ecore_timer_cmp(const void *d1, const void *d2) +{ + const Ecore_Timer *t1 = d1; + const Ecore_Timer *t2 = d2; + + return (int) t1->in - t2->in; +}