summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgeniusgogo <[email protected]>2023-12-22 10:18:33 +0800
committerGitHub <[email protected]>2023-12-22 10:18:33 +0800
commita01b66d57bbc5465854e81a9b6696f067847460b (patch)
tree49c0328fa1fb111a779028e1c44f72060d3ac255 /src
parentcdad0c254ad9a9207c32313f9dd8b50e500fed65 (diff)
fix smp rt_timer deadlock. (#8389)
Diffstat (limited to 'src')
-rw-r--r--src/timer.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/src/timer.c b/src/timer.c
index 98e8f6defb..359cca50e8 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -416,38 +416,13 @@ RTM_EXPORT(rt_timer_delete);
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
-rt_err_t rt_timer_start(rt_timer_t timer)
+static rt_err_t _timer_start(rt_list_t *timer_list, rt_timer_t timer)
{
unsigned int row_lvl;
- rt_list_t *timer_list;
- rt_base_t level;
rt_list_t *row_head[RT_TIMER_SKIP_LIST_LEVEL];
unsigned int tst_nr;
static unsigned int random_nr;
- struct rt_spinlock *spinlock;
-
- /* parameter check */
- RT_ASSERT(timer != RT_NULL);
- RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
-
-#ifdef RT_USING_TIMER_SOFT
- if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
- {
- /* insert timer to soft timer list */
- timer_list = _soft_timer_list;
- spinlock = &_soft_spinlock;
- }
- else
-#endif /* RT_USING_TIMER_SOFT */
- {
- /* insert timer to system timer list */
- timer_list = _timer_list;
- spinlock = &_hard_spinlock;
- }
-
- /* stop timer firstly */
- level = rt_spin_lock_irqsave(spinlock);
/* remove timer from list */
_timer_remove(timer);
/* change status of timer */
@@ -523,10 +498,46 @@ rt_err_t rt_timer_start(rt_timer_t timer)
}
#endif /* RT_USING_TIMER_SOFT */
- rt_spin_unlock_irqrestore(spinlock, level);
+ return RT_EOK;
+}
+/**
+ * @brief This function will start the timer
+ *
+ * @param timer the timer to be started
+ *
+ * @return the operation status, RT_EOK on OK, -RT_ERROR on error
+ */
+rt_err_t rt_timer_start(rt_timer_t timer)
+{
+ struct rt_spinlock *spinlock;
+ rt_list_t *timer_list;
+ rt_base_t level;
+ rt_err_t err;
- return RT_EOK;
+ /* parameter check */
+ RT_ASSERT(timer != RT_NULL);
+ RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
+
+#ifdef RT_USING_TIMER_SOFT
+ if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
+ {
+ timer_list = _soft_timer_list;
+ spinlock = &_soft_spinlock;
+ }
+ else
+#endif /* RT_USING_TIMER_SOFT */
+ {
+ timer_list = _timer_list;
+ spinlock = &_hard_spinlock;
+ }
+
+ /* stop timer firstly */
+ level = rt_spin_lock_irqsave(spinlock);
+ err = _timer_start(timer_list, timer);
+ rt_spin_unlock_irqrestore(spinlock, level);
+
+ return err;
}
RTM_EXPORT(rt_timer_start);
@@ -718,7 +729,7 @@ void rt_timer_check(void)
{
/* start it */
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
- rt_timer_start(t);
+ _timer_start(_timer_list, t);
}
}
else break;
@@ -808,7 +819,7 @@ void rt_soft_timer_check(void)
{
/* start it */
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
- rt_timer_start(t);
+ _timer_start(_soft_timer_list, t);
}
}
else break; /* not check anymore */