runtime configurable timer precision

One can now configure the maximum acceptable delay to be introduced by
Ecore so possibly more timers will be dispatched together, reducing
wakeups and saving more power.



SVN revision: 37607
This commit is contained in:
Gustavo Sverzut Barbieri 2008-11-13 20:42:01 +00:00
parent d5216f9ea7
commit 14243bc1b3
2 changed files with 87 additions and 9 deletions

View File

@ -302,6 +302,9 @@ extern "C" {
EAPI void ecore_timer_delay(Ecore_Timer *timer, double add);
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 Ecore_Animator *ecore_animator_add(int (*func) (void *data), const void *data);
EAPI void *ecore_animator_del(Ecore_Animator *animator);
EAPI void ecore_animator_frametime_set(double frametime);

View File

@ -8,6 +8,7 @@ static int timers_delete_me = 0;
static Ecore_Timer *timers = NULL;
static Ecore_Timer *suspended = NULL;
static double last_check = 0.0;
static double precision = 10.0 / 1000000.0;
/**
* @defgroup Ecore_Time_Group Ecore Time Functions
@ -16,6 +17,52 @@ static double last_check = 0.0;
* retrieve it in a given format, and those that create events based on it.
*/
/**
* Retrieves the current precision used by timer infrastructure.
*
* @see ecore_timer_precision_set()
*/
EAPI double
ecore_timer_precision_get(void)
{
return precision;
}
/**
* Sets the precision to be used by timer infrastructure.
*
* When system calculates time to expire the next timer we'll be able
* to delay the timer by the given amount so more timers will fit in
* the same dispatch, waking up the system less often and thus being
* able to save power.
*
* Be aware that kernel may delay delivery even further, these delays
* are always possible due other tasks having higher priorities or
* other scheduler policies.
*
* Example:
* We have 2 timers, one that expires in a 2.0s and another that
* expires in 2.1s, if precision is 0.1s, then the Ecore will request
* for the next expire to happen in 2.1s and not 2.0s and another one
* of 0.1 as it would before.
*
* @note Ecore is smart enough to see if there are timers in the
* precision range, if it does not, in our example if no second timer
* in (T + precision) existed, then it would use the minimum timeout.
*
* @param value allowed introduced timeout delay, in seconds.
*/
EAPI void
ecore_timer_precision_set(double value)
{
if (value < 0.0)
{
fprintf(stderr, "ERROR: precision %f less than zero, ignored\n", value);
return;
}
precision = value;
}
/**
* Creates a timer to call the given function in the given period of time.
* @param in The interval in seconds.
@ -281,23 +328,51 @@ _ecore_timer_enable_new(void)
}
}
static inline Ecore_Timer *
_ecore_timer_first_get(void)
{
Ecore_Timer *timer = (Ecore_Timer *)timers;
while ((timer) && ((timer->delete_me) || (timer->just_added)))
timer = (Ecore_Timer *)((Ecore_List2 *)timer)->next;
return timer;
}
static inline Ecore_Timer *
_ecore_timer_after_get(Ecore_Timer *base)
{
Ecore_Timer *timer = (Ecore_Timer *)((Ecore_List2 *)base)->next;
double maxtime = base->at + precision;
while ((timer) && ((timer->delete_me) || (timer->just_added)) && (timer->at <= maxtime))
timer = (Ecore_Timer *)((Ecore_List2 *)timer)->next;
if ((!timer) || (timer->at > maxtime))
return NULL;
return timer;
}
double
_ecore_timer_next_get(void)
{
double now;
double in;
Ecore_Timer *timer;
if (!timers) return -1;
Ecore_Timer *first, *second;
first = _ecore_timer_first_get();
if (!first) return -1;
second = _ecore_timer_after_get(first);
if (second)
first = second;
now = ecore_loop_time_get();
timer = (Ecore_Timer *)timers;
while ((timer) && ((timer->delete_me) || (timer->just_added)))
timer = (Ecore_Timer *)((Ecore_List2 *)timer)->next;
if (!timer) return -1;
in = timer->at - now;
in = first->at - now;
if (in < 0) in = 0;
return in;
}
}
int
_ecore_timer_call(double when)