Commit 243cc4d3 authored by Simon Morlat's avatar Simon Morlat

add method to override ticking function

parent 443bd0fd
......@@ -40,11 +40,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
* Structure for method getting time in miliseconds from an external source.
* Function pointer for method getting time in miliseconds from an external source.
* @var MSTickerTimeFunc
*/
typedef uint64_t (*MSTickerTimeFunc)(void *);
/**
* Function pointer for method waiting next tick from an external source.
* @var MSTickerTickFunc
* It shall return the number of late milliseconds, if this value is known.
*/
typedef int (*MSTickerTickFunc)(void *, uint64_t ticker_virtual_time);
/**
* Enum for ticker priority
**/
......@@ -72,6 +79,8 @@ struct _MSTicker
char *name;
double av_load; /*average load of the ticker */
MSTickerPrio prio;
MSTickerTickFunc wait_next_tick;
void *wait_next_tick_data;
bool_t run; /* flag to indicate whether the ticker must be run or not */
};
......@@ -182,6 +191,7 @@ MS2_PUBLIC void ms_ticker_destroy(MSTicker *ticker);
* Override MSTicker's time function.
* This can be used to control the ticker from an external time provider, for example the
* clock of a sound card.
* WARNING: this must not be used in conjunction with ms_ticker_set_tick_func().
*
* @param ticker A #MSTicker object.
* @param func A replacement method for calculating "current time"
......@@ -189,6 +199,17 @@ MS2_PUBLIC void ms_ticker_destroy(MSTicker *ticker);
*/
MS2_PUBLIC void ms_ticker_set_time_func(MSTicker *ticker, MSTickerTimeFunc func, void *user_data);
/**
* Override MSTicker's ticking function.
* This can be used to control the ticker from an external ticking source, for example an interrupt, an event on a file descriptor, etc.
* WARNING: this must not be used in conjunction with ms_ticker_set_time_func().
*
* @param ticker A #MSTicker object.
* @param func A replacement method waiting the next tick.
* @param user_data Any pointer to user private data.
*/
MS2_PUBLIC void ms_ticker_set_tick_func(MSTicker *ticker, MSTickerTickFunc func, void *user_data);
/**
* Print on stdout all filters of a ticker. (INTERNAL: DO NOT USE)
*
......
......@@ -42,8 +42,9 @@ static const double smooth_coef=0.9;
#define TICKER_INTERVAL 10
void * ms_ticker_run(void *s);
static void * ms_ticker_run(void *s);
static uint64_t get_cur_time_ms(void *);
static int wait_next_tick(void *, uint64_t virt_ticker_time);
static void ms_ticker_start(MSTicker *s){
s->run=TRUE;
......@@ -64,6 +65,8 @@ static void ms_ticker_init(MSTicker *ticker, const MSTickerParams *params)
ticker->name=ms_strdup(params->name);
ticker->av_load=0;
ticker->prio=params->prio;
ticker->wait_next_tick=wait_next_tick;
ticker->wait_next_tick_data=ticker;
ms_ticker_start(ticker);
}
......@@ -97,7 +100,7 @@ void ms_ticker_set_priority(MSTicker *ticker, MSTickerPrio prio){
ticker->prio=prio;
}
void ms_ticker_uninit(MSTicker *ticker)
static void ms_ticker_uninit(MSTicker *ticker)
{
ms_ticker_stop(ticker);
ms_free(ticker->name);
......@@ -357,11 +360,29 @@ static void unset_high_prio(int precision){
#endif
}
static int wait_next_tick(void *data, uint64_t virt_ticker_time){
MSTicker *s=(MSTicker*)data;
uint64_t realtime;
int64_t diff;
int late;
while(1){
realtime=s->get_cur_time_ptr(s->get_cur_time_data)-s->orig;
diff=s->time-realtime;
if (diff>0){
/* sleep until next tick */
sleepMs((int)diff);
}else{
late=(int)-diff;
break; /*exit the while loop */
}
}
return late;
}
/*the ticker thread function that executes the filters */
void * ms_ticker_run(void *arg)
{
uint64_t realtime;
int64_t diff;
MSTicker *s=(MSTicker*)arg;
int lastlate=0;
int precision=2;
......@@ -369,13 +390,14 @@ void * ms_ticker_run(void *arg)
precision = set_high_prio(s);
s->ticks=1;
ms_mutex_lock(&s->lock);
s->orig=s->get_cur_time_ptr(s->get_cur_time_data);
ms_mutex_lock(&s->lock);
while(s->run){
s->ticks++;
/*Step 1: run the graphs*/
{
#if TICKER_MEASUREMENTS
MSTimeSpec begin,end;/*used to measure time spent in processing one tick*/
......@@ -390,25 +412,14 @@ void * ms_ticker_run(void *arg)
s->av_load=(smooth_coef*s->av_load)+((1.0-smooth_coef)*iload);
#endif
}
ms_mutex_unlock(&s->lock);
/*Step 2: wait for next tick*/
s->time+=s->interval;
while(1){
realtime=s->get_cur_time_ptr(s->get_cur_time_data)-s->orig;
ms_mutex_unlock(&s->lock);
diff=s->time-realtime;
if (diff>0){
/* sleep until next tick */
sleepMs((int)diff);
}else{
late=(int)-diff;
if (late>s->interval*5 && late>lastlate){
ms_warning("%s: We are late of %d miliseconds.",s->name,late);
}
lastlate=late;
break; /*exit the while loop */
}
ms_mutex_lock(&s->lock);
late=s->wait_next_tick(s->wait_next_tick_data,s->time);
if (late>s->interval*5 && late>lastlate){
ms_warning("%s: We are late of %d miliseconds.",s->name,late);
}
lastlate=late;
ms_mutex_lock(&s->lock);
}
ms_mutex_unlock(&s->lock);
......@@ -421,14 +432,27 @@ void * ms_ticker_run(void *arg)
void ms_ticker_set_time_func(MSTicker *ticker, MSTickerTimeFunc func, void *user_data){
if (func==NULL) func=get_cur_time_ms;
/*ms_mutex_lock(&ticker->lock);*/
ticker->get_cur_time_ptr=func;
ticker->get_cur_time_data=user_data;
/*re-set the origin to take in account that previous function ptr and the
new one may return different times*/
ticker->orig=func(user_data)-ticker->time;
/*ms_mutex_unlock(&ticker->lock);*/
ms_message("ms_ticker_set_time_func: ticker updated.");
ms_message("ms_ticker_set_time_func: ticker's time method updated.");
}
void ms_ticker_set_tick_func(MSTicker *ticker, MSTickerTickFunc func, void *user_data){
if (func==NULL) {
func=wait_next_tick;
user_data=ticker;
}
ticker->wait_next_tick=func;
ticker->wait_next_tick_data=user_data;
/*re-set the origin to take in account that previous function ptr and the
new one may return different times*/
ticker->orig=ticker->get_cur_time_ptr(user_data)-ticker->time;
ms_message("ms_ticker_set_tick_func: ticker's tick method updated.");
}
static void print_graph(MSFilter *f, MSTicker *s, MSList **unschedulable, bool_t force_schedule){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment