Bläddra i källkod

fix the next timeout issue in soft timer

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2484 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 12 år sedan
förälder
incheckning
ea4082b791
1 ändrade filer med 310 tillägg och 289 borttagningar
  1. 310 289
      src/timer.c

+ 310 - 289
src/timer.c

@@ -17,6 +17,7 @@
  * 2009-11-11     LiJin        add soft timer
  * 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
  */
 
 #include <rtthread.h>
@@ -26,6 +27,14 @@
 static rt_list_t rt_timer_list = RT_LIST_OBJECT_INIT(rt_timer_list);
 
 #ifdef RT_USING_TIMER_SOFT
+#ifndef RT_TIMER_THREAD_STACK_SIZE
+#define RT_TIMER_THREAD_STACK_SIZE 512
+#endif
+
+#ifndef RT_TIMER_THREAD_PRIO
+#define RT_TIMER_THREAD_PRIO        0
+#endif
+
 /* soft timer list */
 static rt_list_t rt_soft_timer_list;
 static struct rt_thread timer_thread;
@@ -52,42 +61,42 @@ static void (*rt_timer_timeout_hook)(struct rt_timer *timer);
  */
 void rt_timer_timeout_sethook(void (*hook)(struct rt_timer *timer))
 {
-	rt_timer_timeout_hook = hook;
+    rt_timer_timeout_hook = hook;
 }
 
 /*@}*/
 #endif
 
 static void _rt_timer_init(rt_timer_t timer,
-						   void (*timeout)(void *parameter), void *parameter,
-						   rt_tick_t time, rt_uint8_t flag)
+                           void (*timeout)(void *parameter), void *parameter,
+                           rt_tick_t time, rt_uint8_t flag)
 {
-	/* set flag */
-	timer->parent.flag  = flag;
+    /* set flag */
+    timer->parent.flag  = flag;
 
-	/* set deactivated */
-	timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+    /* set deactivated */
+    timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
 
-	timer->timeout_func = timeout;
-	timer->parameter    = parameter;
+    timer->timeout_func = timeout;
+    timer->parameter    = parameter;
 
-	timer->timeout_tick = 0;
-	timer->init_tick    = time;
+    timer->timeout_tick = 0;
+    timer->init_tick    = time;
 
-	/* initialize timer list */
-	rt_list_init(&(timer->list));
+    /* initialize timer list */
+    rt_list_init(&(timer->list));
 }
 
 static rt_tick_t rt_timer_list_next_timeout(rt_list_t *timer_list)
 {
-	struct rt_timer *timer;
+    struct rt_timer *timer;
 
-	if (rt_list_isempty(timer_list))
-		return RT_TICK_MAX;
-	
-	timer = rt_list_entry(timer_list->next, struct rt_timer, list);
+    if (rt_list_isempty(timer_list))
+        return RT_TICK_MAX;
+    
+    timer = rt_list_entry(timer_list->next, struct rt_timer, list);
 
-	return timer->timeout_tick;
+    return timer->timeout_tick;
 }
 
 /**
@@ -108,17 +117,17 @@ static rt_tick_t rt_timer_list_next_timeout(rt_list_t *timer_list)
  * @param flag the flag of timer
  */
 void rt_timer_init(rt_timer_t timer,
-				   const char *name,
-				   void (*timeout)(void *parameter), void *parameter,
-				   rt_tick_t time, rt_uint8_t flag)
+                   const char *name,
+                   void (*timeout)(void *parameter), void *parameter,
+                   rt_tick_t time, rt_uint8_t flag)
 {
-	/* timer check */
-	RT_ASSERT(timer != RT_NULL);
+    /* timer check */
+    RT_ASSERT(timer != RT_NULL);
 
-	/* timer object initialization */
-	rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
+    /* timer object initialization */
+    rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
 
-	_rt_timer_init(timer, timeout, parameter, time, flag);
+    _rt_timer_init(timer, timeout, parameter, time, flag);
 }
 RTM_EXPORT(rt_timer_init);
 
@@ -131,23 +140,23 @@ RTM_EXPORT(rt_timer_init);
  */
 rt_err_t rt_timer_detach(rt_timer_t timer)
 {
-	register rt_base_t level;
+    register rt_base_t level;
 
-	/* timer check */
-	RT_ASSERT(timer != RT_NULL);
+    /* timer check */
+    RT_ASSERT(timer != RT_NULL);
 
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
 
-	/* remove it from timer list */
-	rt_list_remove(&(timer->list));
+    /* remove it from timer list */
+    rt_list_remove(&(timer->list));
 
-	/* enable interrupt */
-	rt_hw_interrupt_enable(level);
+    /* enable interrupt */
+    rt_hw_interrupt_enable(level);
 
-	rt_object_detach((rt_object_t)timer);
+    rt_object_detach((rt_object_t)timer);
 
-	return -RT_EOK;
+    return -RT_EOK;
 }
 RTM_EXPORT(rt_timer_detach);
 
@@ -164,20 +173,20 @@ RTM_EXPORT(rt_timer_detach);
  * @return the created timer object
  */
 rt_timer_t rt_timer_create(const char *name, void (*timeout)(void *parameter),
-		void *parameter, rt_tick_t time, rt_uint8_t flag)
+        void *parameter, rt_tick_t time, rt_uint8_t flag)
 {
-	struct rt_timer *timer;
+    struct rt_timer *timer;
 
-	/* allocate a object */
-	timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name);
-	if (timer == RT_NULL)
-	{
-		return RT_NULL;
-	}
+    /* allocate a object */
+    timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name);
+    if (timer == RT_NULL)
+    {
+        return RT_NULL;
+    }
 
-	_rt_timer_init(timer, timeout, parameter, time, flag);
+    _rt_timer_init(timer, timeout, parameter, time, flag);
 
-	return timer;
+    return timer;
 }
 RTM_EXPORT(rt_timer_create);
 
@@ -190,23 +199,23 @@ RTM_EXPORT(rt_timer_create);
  */
 rt_err_t rt_timer_delete(rt_timer_t timer)
 {
-	register rt_base_t level;
+    register rt_base_t level;
 
-	/* timer check */
-	RT_ASSERT(timer != RT_NULL);
+    /* timer check */
+    RT_ASSERT(timer != RT_NULL);
 
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
 
-	/* remove it from timer list */
-	rt_list_remove(&(timer->list));
+    /* remove it from timer list */
+    rt_list_remove(&(timer->list));
 
-	/* enable interrupt */
-	rt_hw_interrupt_enable(level);
+    /* enable interrupt */
+    rt_hw_interrupt_enable(level);
 
-	rt_object_delete((rt_object_t)timer);
+    rt_object_delete((rt_object_t)timer);
 
-	return -RT_EOK;
+    return -RT_EOK;
 }
 RTM_EXPORT(rt_timer_delete);
 #endif
@@ -220,76 +229,76 @@ RTM_EXPORT(rt_timer_delete);
  */
 rt_err_t rt_timer_start(rt_timer_t timer)
 {
-	struct rt_timer *t;
-	register rt_base_t level;
-	rt_list_t *n, *timer_list;
+    struct rt_timer *t;
+    register rt_base_t level;
+    rt_list_t *n, *timer_list;
 
-	/* timer check */
-	RT_ASSERT(timer != RT_NULL);
-	if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
-		return -RT_ERROR;
+    /* timer check */
+    RT_ASSERT(timer != RT_NULL);
+    if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
+        return -RT_ERROR;
 
-	RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
+    RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
 
-	/* get timeout tick, the max timeout tick shall not great than RT_TICK_MAX/2 */
-	RT_ASSERT(timer->init_tick < RT_TICK_MAX/2);
-	timer->timeout_tick = rt_tick_get() + timer->init_tick;
+    /* get timeout tick, the max timeout tick shall not great than RT_TICK_MAX/2 */
+    RT_ASSERT(timer->init_tick < RT_TICK_MAX/2);
+    timer->timeout_tick = rt_tick_get() + timer->init_tick;
 
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
 
 #ifdef RT_USING_TIMER_SOFT
-	if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
-	{
-		/* insert timer to soft timer list */
-		timer_list = &rt_soft_timer_list;
-	}
-	else
+    if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
+    {
+        /* insert timer to soft timer list */
+        timer_list = &rt_soft_timer_list;
+    }
+    else
 #endif
-	{
-		/* insert timer to system timer list */
-		timer_list = &rt_timer_list;
-	}
-
-	for (n = timer_list->next; n != timer_list; n = n->next)
-	{
-		t = rt_list_entry(n, struct rt_timer, list);
-		
-		/*
-		 * It supposes that the new tick shall less than the half duration of
-		 * tick max.
-		 */
-		if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX/2)
-		{
-			rt_list_insert_before(n, &(timer->list));
-			break;
-		}
-	}
-	/* no found suitable position in timer list */
-	if (n == timer_list)
-	{
-		rt_list_insert_before(n, &(timer->list));
-	}
-
-	timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;
-
-	/* enable interrupt */
-	rt_hw_interrupt_enable(level);
+    {
+        /* insert timer to system timer list */
+        timer_list = &rt_timer_list;
+    }
+
+    for (n = timer_list->next; n != timer_list; n = n->next)
+    {
+        t = rt_list_entry(n, struct rt_timer, list);
+        
+        /*
+         * It supposes that the new tick shall less than the half duration of
+         * tick max.
+         */
+        if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX/2)
+        {
+            rt_list_insert_before(n, &(timer->list));
+            break;
+        }
+    }
+    /* no found suitable position in timer list */
+    if (n == timer_list)
+    {
+        rt_list_insert_before(n, &(timer->list));
+    }
+
+    timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;
+
+    /* enable interrupt */
+    rt_hw_interrupt_enable(level);
 
 #ifdef RT_USING_TIMER_SOFT
-	if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
-	{
-		/* check whether timer thread is ready */
-		if (timer_thread.stat != RT_THREAD_READY)
-		{
-			/* resume timer thread to check soft timer */
-			rt_thread_resume(&timer_thread);
-			rt_schedule();
-		}
-	}
+    if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
+    {
+        /* check whether timer thread is ready */
+        if (timer_thread.stat != RT_THREAD_READY)
+        {
+            /* resume timer thread to check soft timer */
+            rt_thread_resume(&timer_thread);
+            rt_schedule();
+        }
+    }
 #endif
 
-	return -RT_EOK;
+    return -RT_EOK;
 }
 RTM_EXPORT(rt_timer_start);
 
@@ -302,28 +311,28 @@ RTM_EXPORT(rt_timer_start);
  */
 rt_err_t rt_timer_stop(rt_timer_t timer)
 {
-	register rt_base_t level;
+    register rt_base_t level;
 
-	/* timer check */
-	RT_ASSERT(timer != RT_NULL);
-	if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
-		return -RT_ERROR;
+    /* timer check */
+    RT_ASSERT(timer != RT_NULL);
+    if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
+        return -RT_ERROR;
 
-	RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent)));
+    RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent)));
 
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
 
-	/* remove it from timer list */
-	rt_list_remove(&(timer->list));
+    /* remove it from timer list */
+    rt_list_remove(&(timer->list));
 
-	/* enable interrupt */
-	rt_hw_interrupt_enable(level);
+    /* enable interrupt */
+    rt_hw_interrupt_enable(level);
 
-	/* change stat */
-	timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+    /* change stat */
+    timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
 
-	return RT_EOK;
+    return RT_EOK;
 }
 RTM_EXPORT(rt_timer_stop);
 
@@ -338,29 +347,29 @@ RTM_EXPORT(rt_timer_stop);
  */
 rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg)
 {
-	/* timer check */
-	RT_ASSERT(timer != RT_NULL);
+    /* timer check */
+    RT_ASSERT(timer != RT_NULL);
 
-	switch (cmd)
-	{
-	case RT_TIMER_CTRL_GET_TIME:
-		*(rt_tick_t *)arg = timer->init_tick;
-		break;
+    switch (cmd)
+    {
+    case RT_TIMER_CTRL_GET_TIME:
+        *(rt_tick_t *)arg = timer->init_tick;
+        break;
 
-	case RT_TIMER_CTRL_SET_TIME:
-		timer->init_tick = *(rt_tick_t *)arg;
-		break;
+    case RT_TIMER_CTRL_SET_TIME:
+        timer->init_tick = *(rt_tick_t *)arg;
+        break;
 
-	case RT_TIMER_CTRL_SET_ONESHOT:
-		timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
-		break;
+    case RT_TIMER_CTRL_SET_ONESHOT:
+        timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
+        break;
 
-	case RT_TIMER_CTRL_SET_PERIODIC:
-		timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
-		break;
-	}
+    case RT_TIMER_CTRL_SET_PERIODIC:
+        timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
+        break;
+    }
 
-	return RT_EOK;
+    return RT_EOK;
 }
 RTM_EXPORT(rt_timer_control);
 
@@ -372,61 +381,61 @@ RTM_EXPORT(rt_timer_control);
  */
 void rt_timer_check(void)
 {
-	struct rt_timer *t;
-	rt_tick_t current_tick;
-	register rt_base_t level;
-
-	RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));
-
-	current_tick = rt_tick_get();
-
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
-
-	while (!rt_list_isempty(&rt_timer_list))
-	{
-		t = rt_list_entry(rt_timer_list.next, struct rt_timer, list);
-
-		/*
-		 * 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_timeout_hook, (t));
-
-			/* remove timer from timer list firstly */
-			rt_list_remove(&(t->list));
-
-			/* call timeout function */
-			t->timeout_func(t->parameter);
-
-			/* re-get tick */
-			current_tick = rt_tick_get();
-
-			RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
-
-			if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
-					(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
-			{
-				/* start it */
-				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
-				rt_timer_start(t);
-			}
-			else
-			{
-				/* stop timer */
-				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
-			}
-		}
-		else
-			break;
-	}
-
-	/* enable interrupt */
-	rt_hw_interrupt_enable(level);
-
-	RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check leave\n"));
+    struct rt_timer *t;
+    rt_tick_t current_tick;
+    register rt_base_t level;
+
+    RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));
+
+    current_tick = rt_tick_get();
+
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
+
+    while (!rt_list_isempty(&rt_timer_list))
+    {
+        t = rt_list_entry(rt_timer_list.next, struct rt_timer, list);
+
+        /*
+         * 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_timeout_hook, (t));
+
+            /* remove timer from timer list firstly */
+            rt_list_remove(&(t->list));
+
+            /* call timeout function */
+            t->timeout_func(t->parameter);
+
+            /* re-get tick */
+            current_tick = rt_tick_get();
+
+            RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
+
+            if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
+                    (t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
+            {
+                /* start it */
+                t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+                rt_timer_start(t);
+            }
+            else
+            {
+                /* stop timer */
+                t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+            }
+        }
+        else
+            break;
+    }
+
+    /* enable interrupt */
+    rt_hw_interrupt_enable(level);
+
+    RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check leave\n"));
 }
 
 /**
@@ -436,7 +445,7 @@ void rt_timer_check(void)
  */
 rt_tick_t rt_timer_next_timeout_tick(void)
 {
-	return rt_timer_list_next_timeout(&rt_timer_list);
+    return rt_timer_list_next_timeout(&rt_timer_list);
 }
 
 #ifdef RT_USING_TIMER_SOFT
@@ -446,84 +455,96 @@ rt_tick_t rt_timer_next_timeout_tick(void)
  */
 void rt_soft_timer_check(void)
 {
-	rt_tick_t current_tick;
-	rt_list_t *n;
-	struct rt_timer *t;
-
-	RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n"));
-
-	current_tick = rt_tick_get();
-
-	for (n = rt_soft_timer_list.next; n != &(rt_soft_timer_list);)
-	{
-		t = rt_list_entry(n, struct rt_timer, list);
-
-		/*
-		 * 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_timeout_hook, (t));
-
-			/* move node to the next */
-			n = n->next;
-
-			/* remove timer from timer list firstly */
-			rt_list_remove(&(t->list));
-
-			/* call timeout function */
-			t->timeout_func(t->parameter);
-
-			/* re-get tick */
-			current_tick = rt_tick_get();
-
-			RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
-
-			if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
-					(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
-			{
-				/* start it */
-				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
-				rt_timer_start(t);
-			}
-			else
-			{
-				/* stop timer */
-				t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
-			}
-		}
-		else break; /* not check anymore */
-	}
-
-	RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
+    rt_tick_t current_tick;
+    rt_list_t *n;
+    struct rt_timer *t;
+
+    RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n"));
+
+    current_tick = rt_tick_get();
+
+    for (n = rt_soft_timer_list.next; n != &(rt_soft_timer_list);)
+    {
+        t = rt_list_entry(n, struct rt_timer, list);
+
+        /*
+         * 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_timeout_hook, (t));
+
+            /* move node to the next */
+            n = n->next;
+
+            /* remove timer from timer list firstly */
+            rt_list_remove(&(t->list));
+
+            /* call timeout function */
+            t->timeout_func(t->parameter);
+
+            /* re-get tick */
+            current_tick = rt_tick_get();
+
+            RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
+
+            if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
+                    (t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
+            {
+                /* start it */
+                t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+                rt_timer_start(t);
+            }
+            else
+            {
+                /* stop timer */
+                t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+            }
+        }
+        else break; /* not check anymore */
+    }
+
+    RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
 }
 
 /* system timer thread entry */
 static void rt_thread_timer_entry(void *parameter)
 {
-	rt_tick_t next_timeout;
-	
-	while (1)
-	{
-		next_timeout = rt_timer_list_next_timeout(&rt_soft_timer_list);
-		if (next_timeout == RT_TICK_MAX)
-		{
-			rt_thread_suspend(rt_thread_self());
-			rt_schedule();
-		}
-		else
-		{
-			rt_thread_delay(next_timeout);
-		}
-
-		/* lock scheduler */
-		rt_enter_critical();
-		/* check software timer */
-		rt_soft_timer_check();
-		/* unlock scheduler */
-		rt_exit_critical();
-	}
+    rt_tick_t next_timeout;
+    
+    while (1)
+    {
+        /* get the next timeout tick */
+        next_timeout = rt_timer_list_next_timeout(&rt_soft_timer_list);
+        if (next_timeout == RT_TICK_MAX)
+        {
+            /* no software timer exist, suspend self. */
+            rt_thread_suspend(rt_thread_self());
+            rt_schedule();
+        }
+        else
+        {
+            rt_tick_t current_tick;
+
+            /* get current tick */
+            current_tick = rt_tick_get();
+
+            if ((next_timeout - current_tick) < RT_TICK_MAX/2)
+            {
+                /* get the delta timeout tick */
+                next_timeout = next_timeout - current_tick;
+                rt_thread_delay(next_timeout);
+            }
+        }
+
+        /* lock scheduler */
+        rt_enter_critical();
+        /* check software timer */
+        rt_soft_timer_check();
+        /* unlock scheduler */
+        rt_exit_critical();
+    }
 }
 #endif
 
@@ -547,17 +568,17 @@ void rt_system_timer_init(void)
 void rt_system_timer_thread_init(void)
 {
 #ifdef RT_USING_TIMER_SOFT
-	rt_list_init(&rt_soft_timer_list);
+    rt_list_init(&rt_soft_timer_list);
 
-	/* start software timer thread */
-	rt_thread_init(&timer_thread,
-				   "timer",
-				   rt_thread_timer_entry, RT_NULL,
-				   &timer_thread_stack[0], sizeof(timer_thread_stack),
-				   RT_TIMER_THREAD_PRIO, 10);
+    /* start software timer thread */
+    rt_thread_init(&timer_thread,
+                   "timer",
+                   rt_thread_timer_entry, RT_NULL,
+                   &timer_thread_stack[0], sizeof(timer_thread_stack),
+                   RT_TIMER_THREAD_PRIO, 10);
 
-	/* startup */
-	rt_thread_startup(&timer_thread);
+    /* startup */
+    rt_thread_startup(&timer_thread);
 #endif
 }