Skip to content

Commit f516d8b

Browse files
committed
reload timeout_tick with absolute base value
1 parent 6369e89 commit f516d8b

File tree

1 file changed

+47
-71
lines changed

1 file changed

+47
-71
lines changed

src/timer.c

+47-71
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* 2014-07-12 Bernard does not lock scheduler when invoking soft-timer
1818
* timeout function.
1919
* 2021-08-15 supperthomas add the comment
20+
* 2021-12-20 THEWON reload timeout_tick with absolute base value
2021
*/
2122

2223
#include <rtthread.h>
@@ -27,9 +28,6 @@ static rt_list_t _timer_list[RT_TIMER_SKIP_LIST_LEVEL];
2728

2829
#ifdef RT_USING_TIMER_SOFT
2930

30-
#define RT_SOFT_TIMER_IDLE 1
31-
#define RT_SOFT_TIMER_BUSY 0
32-
3331
#ifndef RT_TIMER_THREAD_STACK_SIZE
3432
#define RT_TIMER_THREAD_STACK_SIZE 512
3533
#endif /* RT_TIMER_THREAD_STACK_SIZE */
@@ -38,8 +36,6 @@ static rt_list_t _timer_list[RT_TIMER_SKIP_LIST_LEVEL];
3836
#define RT_TIMER_THREAD_PRIO 0
3937
#endif /* RT_TIMER_THREAD_PRIO */
4038

41-
/* soft timer status */
42-
static rt_uint8_t _soft_timer_status = RT_SOFT_TIMER_IDLE;
4339
/* soft timer list */
4440
static rt_list_t _soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
4541
static struct rt_thread _timer_thread;
@@ -355,28 +351,19 @@ rt_err_t rt_timer_delete(rt_timer_t timer)
355351
RTM_EXPORT(rt_timer_delete);
356352
#endif /* RT_USING_HEAP */
357353

358-
/**
359-
* @brief This function will start the timer
360-
*
361-
* @param timer the timer to be started
362-
*
363-
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
364-
*/
365-
rt_err_t rt_timer_start(rt_timer_t timer)
354+
static rt_err_t _timer_start(rt_timer_t timer, rt_tick_t current_tick)
366355
{
367356
unsigned int row_lvl;
368357
rt_list_t *timer_list;
369358
register rt_base_t level;
370-
register rt_bool_t need_schedule;
371359
rt_list_t *row_head[RT_TIMER_SKIP_LIST_LEVEL];
372360
unsigned int tst_nr;
373361
static unsigned int random_nr;
374362

375363
/* timer check */
376364
RT_ASSERT(timer != RT_NULL);
377365
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
378-
379-
need_schedule = RT_FALSE;
366+
RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2);
380367

381368
/* stop timer firstly */
382369
level = rt_hw_interrupt_disable();
@@ -391,8 +378,7 @@ rt_err_t rt_timer_start(rt_timer_t timer)
391378
* get timeout tick,
392379
* the max timeout tick shall not great than RT_TICK_MAX/2
393380
*/
394-
RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2);
395-
timer->timeout_tick = rt_tick_get() + timer->init_tick;
381+
timer->timeout_tick = current_tick + timer->init_tick;
396382

397383
#ifdef RT_USING_TIMER_SOFT
398384
if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
@@ -469,21 +455,36 @@ rt_err_t rt_timer_start(rt_timer_t timer)
469455
{
470456
/* resume timer thread to check soft timer */
471457
rt_thread_resume(&_timer_thread);
472-
need_schedule = RT_TRUE;
458+
/* enable interrupt */
459+
rt_hw_interrupt_enable(level);
460+
461+
rt_schedule();
462+
463+
return RT_EOK;
473464
}
474465
}
475466
#endif /* RT_USING_TIMER_SOFT */
476467

477468
/* enable interrupt */
478469
rt_hw_interrupt_enable(level);
479470

480-
if (need_schedule)
481-
{
482-
rt_schedule();
483-
}
484-
485471
return RT_EOK;
486472
}
473+
474+
/**
475+
* @brief This function will start the timer
476+
*
477+
* @param timer the timer to be started
478+
*
479+
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
480+
*/
481+
rt_err_t rt_timer_start(rt_timer_t timer)
482+
{
483+
rt_tick_t current_tick;
484+
485+
current_tick = rt_tick_get();
486+
return _timer_start(timer, current_tick);
487+
}
487488
RTM_EXPORT(rt_timer_start);
488489

489490
/**
@@ -589,9 +590,6 @@ void rt_timer_check(void)
589590
struct rt_timer *t;
590591
rt_tick_t current_tick;
591592
register rt_base_t level;
592-
rt_list_t list;
593-
594-
rt_list_init(&list);
595593

596594
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));
597595

@@ -611,16 +609,22 @@ void rt_timer_check(void)
611609
*/
612610
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
613611
{
614-
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
615-
616612
/* remove timer from timer list firstly */
617613
_timer_remove(t);
618-
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC))
614+
615+
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
616+
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
617+
{
618+
/* start it */
619+
_timer_start(t, t->timeout_tick);
620+
}
621+
else
619622
{
620623
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
621624
}
622-
/* add timer to temporary list */
623-
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
625+
626+
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
627+
624628
/* call timeout function */
625629
t->timeout_func(t->parameter);
626630

@@ -629,20 +633,6 @@ void rt_timer_check(void)
629633

630634
RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
631635
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
632-
633-
/* Check whether the timer object is detached or started again */
634-
if (rt_list_isempty(&list))
635-
{
636-
continue;
637-
}
638-
rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
639-
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
640-
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
641-
{
642-
/* start it */
643-
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
644-
rt_timer_start(t);
645-
}
646636
}
647637
else break;
648638
}
@@ -673,12 +663,11 @@ void rt_soft_timer_check(void)
673663
rt_tick_t current_tick;
674664
struct rt_timer *t;
675665
register rt_base_t level;
676-
rt_list_t list;
677-
678-
rt_list_init(&list);
679666

680667
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n"));
681668

669+
current_tick = rt_tick_get();
670+
682671
/* disable interrupt */
683672
level = rt_hw_interrupt_disable();
684673

@@ -687,29 +676,30 @@ void rt_soft_timer_check(void)
687676
t = rt_list_entry(_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
688677
struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
689678

690-
current_tick = rt_tick_get();
691-
692679
/*
693680
* It supposes that the new tick shall less than the half duration of
694681
* tick max.
695682
*/
696683
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
697684
{
698-
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
699-
700685
/* remove timer from timer list firstly */
701686
_timer_remove(t);
702-
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC))
687+
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC)) &&
688+
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED)
689+
{
690+
/* start it */
691+
_timer_start(t, t->timeout_tick);
692+
}
693+
else
703694
{
704695
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
705696
}
706-
/* add timer to temporary list */
707-
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
708697

709-
_soft_timer_status = RT_SOFT_TIMER_BUSY;
710698
/* enable interrupt */
711699
rt_hw_interrupt_enable(level);
712700

701+
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
702+
713703
/* call timeout function */
714704
t->timeout_func(t->parameter);
715705

@@ -718,20 +708,6 @@ void rt_soft_timer_check(void)
718708

719709
/* disable interrupt */
720710
level = rt_hw_interrupt_disable();
721-
722-
_soft_timer_status = RT_SOFT_TIMER_IDLE;
723-
/* Check whether the timer object is detached or started again */
724-
if (rt_list_isempty(&list))
725-
{
726-
continue;
727-
}
728-
rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
729-
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
730-
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
731-
{
732-
/* start it */
733-
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
734-
rt_timer_start(t);
735711
}
736712
}
737713
else break; /* not check anymore */

0 commit comments

Comments
 (0)