|
void rt_timer_check(void) |
|
{ |
|
struct rt_timer *t; |
|
rt_tick_t current_tick; |
|
rt_base_t level; |
|
rt_list_t list; |
|
|
|
RT_ASSERT(rt_interrupt_get_nest() > 0); |
|
|
|
LOG_D("timer check enter"); |
|
|
|
level = rt_spin_lock_irqsave(&_htimer_lock); |
|
|
|
current_tick = rt_tick_get(); |
|
|
|
#ifdef RT_USING_SMP |
|
/* Running on core 0 only */ |
|
if (rt_hw_cpu_id() != 0) |
|
{ |
|
rt_spin_unlock_irqrestore(&_htimer_lock, level); |
|
return; |
|
} |
|
#endif |
|
|
|
rt_list_init(&list); |
|
|
|
while (!rt_list_isempty(&_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) |
|
{ |
|
t = rt_list_entry(_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next, |
|
struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); |
|
|
|
/* |
|
* It supposes that the new tick shall less than the half duration of |
|
* tick max. |
|
*/ |
|
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2) |
|
{ |
|
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t)); |
|
|
|
/* remove timer from timer list firstly */ |
|
_timer_remove(t); |
|
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC)) |
|
{ |
|
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; |
|
} |
|
|
|
t->parent.flag |= RT_TIMER_FLAG_PROCESSING; |
|
/* add timer to temporary list */ |
|
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); |
|
rt_spin_unlock_irqrestore(&_htimer_lock, level); |
|
/* call timeout function */ |
|
t->timeout_func(t->parameter); |
|
|
|
/* re-get tick */ |
|
current_tick = rt_tick_get(); |
|
|
|
RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t)); |
|
LOG_D("current tick: %d", current_tick); |
|
level = rt_spin_lock_irqsave(&_htimer_lock); |
|
|
|
t->parent.flag &= ~RT_TIMER_FLAG_PROCESSING; |
|
|
|
/* Check whether the timer object is detached or started again */ |
|
if (rt_list_isempty(&list)) |
|
{ |
|
continue; |
|
} |
|
rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); |
|
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && |
|
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) |
|
{ |
|
/* start it */ |
|
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; |
|
_timer_start(_timer_list, t); |
|
} |
|
} |
|
else break; |
|
} |
|
rt_spin_unlock_irqrestore(&_htimer_lock, level); |
|
LOG_D("timer check leave"); |
|
} |
rt-thread/src/timer.c
Lines 774 to 843 in b586889
rt-thread/src/timer.c
Lines 670 to 750 in b586889