Skip to content

Commit a101d3d

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

File tree

1 file changed

+48
-74
lines changed

1 file changed

+48
-74
lines changed

src/timer.c

+48-74
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)
@@ -464,26 +450,40 @@ rt_err_t rt_timer_start(rt_timer_t timer)
464450
if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
465451
{
466452
/* check whether timer thread is ready */
467-
if ((_soft_timer_status == RT_SOFT_TIMER_IDLE) &&
468-
((_timer_thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND))
453+
if ((_timer_thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
469454
{
470455
/* resume timer thread to check soft timer */
471456
rt_thread_resume(&_timer_thread);
472-
need_schedule = RT_TRUE;
457+
/* enable interrupt */
458+
rt_hw_interrupt_enable(level);
459+
460+
rt_schedule();
461+
462+
return RT_EOK;
473463
}
474464
}
475465
#endif /* RT_USING_TIMER_SOFT */
476466

477467
/* enable interrupt */
478468
rt_hw_interrupt_enable(level);
479469

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

489489
/**
@@ -589,9 +589,6 @@ void rt_timer_check(void)
589589
struct rt_timer *t;
590590
rt_tick_t current_tick;
591591
register rt_base_t level;
592-
rt_list_t list;
593-
594-
rt_list_init(&list);
595592

596593
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));
597594

@@ -611,16 +608,22 @@ void rt_timer_check(void)
611608
*/
612609
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
613610
{
614-
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
615-
616611
/* remove timer from timer list firstly */
617612
_timer_remove(t);
618-
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC))
613+
614+
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
615+
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
616+
{
617+
/* start it */
618+
_timer_start(t, t->timeout_tick);
619+
}
620+
else
619621
{
620622
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
621623
}
622-
/* add timer to temporary list */
623-
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
624+
625+
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
626+
624627
/* call timeout function */
625628
t->timeout_func(t->parameter);
626629

@@ -629,20 +632,6 @@ void rt_timer_check(void)
629632

630633
RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
631634
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-
}
646635
}
647636
else break;
648637
}
@@ -673,12 +662,11 @@ void rt_soft_timer_check(void)
673662
rt_tick_t current_tick;
674663
struct rt_timer *t;
675664
register rt_base_t level;
676-
rt_list_t list;
677-
678-
rt_list_init(&list);
679665

680666
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n"));
681667

668+
current_tick = rt_tick_get();
669+
682670
/* disable interrupt */
683671
level = rt_hw_interrupt_disable();
684672

@@ -687,29 +675,30 @@ void rt_soft_timer_check(void)
687675
t = rt_list_entry(_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
688676
struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
689677

690-
current_tick = rt_tick_get();
691-
692678
/*
693679
* It supposes that the new tick shall less than the half duration of
694680
* tick max.
695681
*/
696682
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
697683
{
698-
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
699-
700684
/* remove timer from timer list firstly */
701685
_timer_remove(t);
702-
if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC))
686+
if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
687+
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
688+
{
689+
/* start it */
690+
_timer_start(t, t->timeout_tick);
691+
}
692+
else
703693
{
704694
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
705695
}
706-
/* add timer to temporary list */
707-
rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
708696

709-
_soft_timer_status = RT_SOFT_TIMER_BUSY;
710697
/* enable interrupt */
711698
rt_hw_interrupt_enable(level);
712699

700+
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
701+
713702
/* call timeout function */
714703
t->timeout_func(t->parameter);
715704

@@ -718,21 +707,6 @@ void rt_soft_timer_check(void)
718707

719708
/* disable interrupt */
720709
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);
735-
}
736710
}
737711
else break; /* not check anymore */
738712
}

0 commit comments

Comments
 (0)