summaryrefslogtreecommitdiff
path: root/src/timer.c
diff options
context:
space:
mode:
author陈豪 <[email protected]>2014-08-06 22:55:49 +0800
committer陈豪 <[email protected]>2014-08-06 22:55:49 +0800
commit5fc32bf12ef4356ecbd46cfa21079cddb522b5c7 (patch)
tree8f77e59c1bcec59c3c5efd0fe022f3dc0a0c901e /src/timer.c
parent0c8335d5ab046ce9fe36c4e01d5d40e4ba152b49 (diff)
parenta8fadf15b1828569e7684049d983cc6cb7fda2c9 (diff)
Merge pull request #1 from RT-Thread/master
sync
Diffstat (limited to 'src/timer.c')
-rw-r--r--src/timer.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/timer.c b/src/timer.c
index ac8a148d8d..f71e40fcd6 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -28,6 +28,8 @@
* 2010-05-12 Bernard fix the timer check bug.
* 2010-11-02 Charlie re-implement tick overflow issue
* 2012-12-15 Bernard fix the next timeout issue in soft timer
+ * 2014-07-12 Bernard does not lock scheduler when invoking soft-timer
+ * timeout function.
*/
#include <rtthread.h>
@@ -128,6 +130,7 @@ rt_inline void _rt_timer_remove(rt_timer_t timer)
}
}
+#if RT_DEBUG_TIMER
static int rt_timer_count_height(struct rt_timer *timer)
{
int i, cnt = 0;
@@ -155,6 +158,7 @@ void rt_timer_dump(rt_list_t timer_heads[])
}
rt_kprintf("\n");
}
+#endif
/**
* @addtogroup Clock
@@ -298,8 +302,14 @@ rt_err_t rt_timer_start(rt_timer_t timer)
/* timer check */
RT_ASSERT(timer != RT_NULL);
- if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
- return -RT_ERROR;
+
+ /* stop timer firstly */
+ level = rt_hw_interrupt_disable();
+ /* remove timer from list */
+ _rt_timer_remove(timer);
+ /* change status of timer */
+ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+ rt_hw_interrupt_enable(level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
@@ -560,6 +570,9 @@ void rt_soft_timer_check(void)
current_tick = rt_tick_get();
+ /* lock scheduler */
+ rt_enter_critical();
+
for (n = rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL-1].next;
n != &(rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL-1]);)
{
@@ -579,6 +592,8 @@ void rt_soft_timer_check(void)
/* remove timer from timer list firstly */
_rt_timer_remove(t);
+ /* not lock scheduler when performing timeout function */
+ rt_exit_critical();
/* call timeout function */
t->timeout_func(t->parameter);
@@ -587,6 +602,9 @@ void rt_soft_timer_check(void)
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
+ /* lock scheduler */
+ rt_enter_critical();
+
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
{
@@ -603,6 +621,9 @@ void rt_soft_timer_check(void)
else break; /* not check anymore */
}
+ /* unlock scheduler */
+ rt_exit_critical();
+
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
}
@@ -636,12 +657,8 @@ static void rt_thread_timer_entry(void *parameter)
}
}
- /* lock scheduler */
- rt_enter_critical();
/* check software timer */
rt_soft_timer_check();
- /* unlock scheduler */
- rt_exit_critical();
}
}
#endif