From 7879986e387a9276438b51aa543e809df6a75a09 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Wed, 8 May 2024 09:27:38 +0800 Subject: [PATCH] [timer] The rt_timer_check and _soft_timer_check functions are merged (#8884) --- src/timer.c | 228 ++++++++++++++++++++-------------------------------- 1 file changed, 86 insertions(+), 142 deletions(-) diff --git a/src/timer.c b/src/timer.c index 143bbebb12..4db2f09a96 100644 --- a/src/timer.c +++ b/src/timer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2022, RT-Thread Development Team + * Copyright (c) 2006-2024, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -21,6 +21,7 @@ * 2022-04-19 Stanley Correct descriptions * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-01-25 Shell add RT_TIMER_FLAG_THREAD_TIMER for timer to sync with sched + * 2024-05-01 wdfk-prog The rt_timer_check and _soft_timer_check functions are merged */ #include @@ -472,6 +473,84 @@ static rt_err_t _timer_start(rt_list_t *timer_list, rt_timer_t timer) return RT_EOK; } +/** + * @brief This function will check timer list, if a timeout event happens, + * the corresponding timeout function will be invoked. + * + * @param timer_list The timer list to check. + * @param lock The lock for the timer list. + */ +static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) +{ + struct rt_timer *t; + rt_tick_t current_tick; + rt_base_t level; + rt_list_t list; + + level = rt_spin_lock_irqsave(lock); + + current_tick = rt_tick_get(); + + 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]); + + /* re-get tick */ + current_tick = rt_tick_get(); + + /* + * 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(lock, level); + + /* call timeout function */ + t->timeout_func(t->parameter); + + RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t)); + LOG_D("current tick: %d", current_tick); + + level = rt_spin_lock_irqsave(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(lock, level); +} + /** * @brief This function will start the timer * @@ -669,83 +748,19 @@ RTM_EXPORT(rt_timer_control); */ 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_cpu_get_id() != 0) { - rt_spin_unlock_irqrestore(&_htimer_lock, level); return; } #endif + _timer_check(_timer_list, &_htimer_lock); - 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"); } @@ -767,81 +782,6 @@ rt_tick_t rt_timer_next_timeout_tick(void) } #ifdef RT_USING_TIMER_SOFT -/** - * @brief This function will check software-timer list, if a timeout event happens, the - * corresponding timeout function will be invoked. - */ -static void _soft_timer_check(void) -{ - rt_tick_t current_tick; - struct rt_timer *t; - rt_base_t level; - rt_list_t list; - - rt_list_init(&list); - LOG_D("software timer check enter"); - level = rt_spin_lock_irqsave(&_stimer_lock); - - while (!rt_list_isempty(&_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) - { - t = rt_list_entry(_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next, - struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); - - current_tick = rt_tick_get(); - - /* - * 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(&_stimer_lock, level); - - /* call timeout function */ - t->timeout_func(t->parameter); - - RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t)); - LOG_D("current tick: %d", current_tick); - - level = rt_spin_lock_irqsave(&_stimer_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(_soft_timer_list, t); - } - } - else break; /* not check anymore */ - } - - rt_spin_unlock_irqrestore(&_stimer_lock, level); - - LOG_D("software timer check leave"); -} - /** * @brief System timer thread entry * @@ -884,7 +824,11 @@ static void _timer_thread_entry(void *parameter) } /* check software timer */ - _soft_timer_check(); + LOG_D("software timer check enter"); + + _timer_check(_soft_timer_list, &_stimer_lock); + + LOG_D("software timer check leave"); } } #endif /* RT_USING_TIMER_SOFT */