From a6ec1a904e94755663215925d50afa9ed79a0246 Mon Sep 17 00:00:00 2001 From: yueling hu <502966985@qq.com> Date: Wed, 4 Jun 2025 07:33:46 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E4=BB=A3=E7=A0=81=EF=BC=8Cfix=20timer=20?= =?UTF-8?q?=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ipc.c | 118 +++++++++----------------------------------------- src/mempool.c | 10 ++--- src/signal.c | 8 +--- src/thread.c | 22 ++++------ src/timer.c | 10 ++--- 5 files changed, 37 insertions(+), 131 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index 35c0146dd33..05ad3d52ade 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -46,6 +46,8 @@ * 2022-10-16 Bernard add prioceiling feature in mutex * 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable + * 2025-06-01 htl5241 remove redundancy rt_schedule() + * fix timer overflow */ #include @@ -626,9 +628,6 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag) /* enable interrupt */ rt_spin_unlock_irqrestore(&(sem->spinlock), level); - /* do schedule */ - rt_schedule(); - if (thread->error != RT_EOK) { return thread->error > 0 ? -thread->error : thread->error; @@ -695,16 +694,12 @@ RTM_EXPORT(rt_sem_trytake); rt_err_t rt_sem_release(rt_sem_t sem) { rt_base_t level; - rt_bool_t need_schedule; - /* parameter check */ RT_ASSERT(sem != RT_NULL); RT_ASSERT(rt_object_get_type(&sem->parent.parent) == RT_Object_Class_Semaphore); RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(sem->parent.parent))); - need_schedule = RT_FALSE; - level = rt_spin_lock_irqsave(&(sem->spinlock)); LOG_D("thread %s releases sem:%s, which value is: %d", @@ -716,7 +711,6 @@ rt_err_t rt_sem_release(rt_sem_t sem) { /* resume the suspended thread */ rt_susp_list_dequeue(&(sem->parent.suspend_thread), RT_EOK); - need_schedule = RT_TRUE; } else { @@ -733,10 +727,6 @@ rt_err_t rt_sem_release(rt_sem_t sem) rt_spin_unlock_irqrestore(&(sem->spinlock), level); - /* resume a thread, re-schedule */ - if (need_schedule == RT_TRUE) - rt_schedule(); - return RT_EOK; } RTM_EXPORT(rt_sem_release); @@ -778,14 +768,12 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) /* set new value */ sem->value = (rt_uint16_t)value; rt_spin_unlock_irqrestore(&(sem->spinlock), level); - rt_schedule(); return RT_EOK; } else if (cmd == RT_IPC_CMD_SET_VLIMIT) { rt_ubase_t max_value; - rt_bool_t need_schedule = RT_FALSE; max_value = (rt_uint16_t)((rt_uintptr_t)arg); if (max_value > RT_SEM_VALUE_MAX || max_value < 1) @@ -800,18 +788,12 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) { /* resume all waiting thread */ rt_susp_list_resume_all(&sem->parent.suspend_thread, RT_ERROR); - need_schedule = RT_TRUE; } } /* set new value */ sem->max_value = max_value; rt_spin_unlock_irqrestore(&(sem->spinlock), level); - if (need_schedule) - { - rt_schedule(); - } - return RT_EOK; } @@ -1445,9 +1427,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend rt_spin_unlock(&(mutex->spinlock)); - /* do schedule */ - rt_schedule(); - rt_spin_lock(&(mutex->spinlock)); if (mutex->owner == thread) @@ -1590,14 +1569,10 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) { rt_sched_lock_level_t slvl; struct rt_thread *thread; - rt_bool_t need_schedule; - /* parameter check */ RT_ASSERT(mutex != RT_NULL); RT_ASSERT(rt_object_get_type(&mutex->parent.parent) == RT_Object_Class_Mutex); - need_schedule = RT_FALSE; - /* only thread could release mutex because we need test the ownership */ RT_DEBUG_IN_THREAD_CONTEXT; @@ -1631,8 +1606,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) rt_list_remove(&mutex->taken_list); /* whether change the thread priority */ - need_schedule = _check_and_update_prio(thread, mutex); - + _check_and_update_prio(thread, mutex); /* wakeup suspended thread */ if (!rt_list_isempty(&mutex->parent.suspend_thread)) { @@ -1683,8 +1657,6 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) { mutex->priority = 0xff; } - - need_schedule = RT_TRUE; } else { @@ -1707,10 +1679,6 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) rt_spin_unlock(&(mutex->spinlock)); - /* perform a schedule */ - if (need_schedule == RT_TRUE) - rt_schedule(); - return RT_EOK; } RTM_EXPORT(rt_mutex_release); @@ -1968,7 +1936,6 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) rt_sched_lock_level_t slvl; rt_base_t level; rt_base_t status; - rt_bool_t need_schedule; rt_uint32_t need_clear_set = 0; /* parameter check */ @@ -1978,8 +1945,6 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) if (set == 0) return -RT_ERROR; - need_schedule = RT_FALSE; - level = rt_spin_lock_irqsave(&(event->spinlock)); /* set event */ @@ -2039,8 +2004,6 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) rt_sched_thread_ready(thread); thread->error = RT_EOK; - /* need do a scheduling */ - need_schedule = RT_TRUE; } } if (need_clear_set) @@ -2052,10 +2015,6 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) rt_sched_unlock(slvl); rt_spin_unlock_irqrestore(&(event->spinlock), level); - /* do a schedule */ - if (need_schedule == RT_TRUE) - rt_schedule(); - return RT_EOK; } RTM_EXPORT(rt_event_send); @@ -2195,9 +2154,6 @@ static rt_err_t _rt_event_recv(rt_event_t event, rt_spin_unlock_irqrestore(&(event->spinlock), level); - /* do a schedule */ - rt_schedule(); - if (thread->error != RT_EOK) { /* return error */ @@ -2284,8 +2240,6 @@ rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg) rt_spin_unlock_irqrestore(&(event->spinlock), level); - rt_schedule(); - return RT_EOK; } @@ -2567,7 +2521,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; /* parameter check */ @@ -2578,7 +2532,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -2622,7 +2576,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mb_send_wait: start timer of thread:%s", thread->parent.name); @@ -2635,9 +2589,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, } rt_spin_unlock_irqrestore(&(mb->spinlock), level); - /* re-schedule */ - rt_schedule(); - /* resume from suspend state */ if (thread->error != RT_EOK) { @@ -2650,8 +2601,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -2682,8 +2632,6 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, rt_spin_unlock_irqrestore(&(mb->spinlock), level); - rt_schedule(); - return RT_EOK; } rt_spin_unlock_irqrestore(&(mb->spinlock), level); @@ -2806,8 +2754,6 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) rt_spin_unlock_irqrestore(&(mb->spinlock), level); - rt_schedule(); - return RT_EOK; } rt_spin_unlock_irqrestore(&(mb->spinlock), level); @@ -2846,7 +2792,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; /* parameter check */ @@ -2857,7 +2803,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -2902,7 +2848,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mb_recv: start timer of thread:%s", thread->parent.name); @@ -2916,9 +2862,6 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo rt_spin_unlock_irqrestore(&(mb->spinlock), level); - /* re-schedule */ - rt_schedule(); - /* resume from suspend state */ if (thread->error != RT_EOK) { @@ -2930,8 +2873,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -2960,8 +2902,6 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mb->parent.parent))); - rt_schedule(); - return RT_EOK; } rt_spin_unlock_irqrestore(&(mb->spinlock), level); @@ -3029,8 +2969,6 @@ rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg) rt_spin_unlock_irqrestore(&(mb->spinlock), level); - rt_schedule(); - return RT_EOK; } @@ -3382,7 +3320,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, { rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; struct rt_thread *thread; rt_err_t ret; @@ -3402,7 +3340,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, return -RT_ERROR; /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -3447,7 +3385,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mq_send_wait: start timer of thread:%s", thread->parent.name); @@ -3461,9 +3399,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, rt_spin_unlock_irqrestore(&(mq->spinlock), level); - /* re-schedule */ - rt_schedule(); - /* resume from suspend state */ if (thread->error != RT_EOK) { @@ -3475,8 +3410,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -3556,8 +3490,6 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, rt_spin_unlock_irqrestore(&(mq->spinlock), level); - rt_schedule(); - return RT_EOK; } rt_spin_unlock_irqrestore(&(mq->spinlock), level); @@ -3714,8 +3646,6 @@ rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size) rt_spin_unlock_irqrestore(&(mq->spinlock), level); - rt_schedule(); - return RT_EOK; } @@ -3765,7 +3695,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, struct rt_thread *thread; rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; rt_size_t len; @@ -3781,7 +3711,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mq->parent.parent))); @@ -3826,7 +3756,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("set thread:%s to timer list", thread->parent.name); @@ -3840,9 +3770,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, rt_spin_unlock_irqrestore(&(mq->spinlock), level); - /* re-schedule */ - rt_schedule(); - /* recv message */ if (thread->error != RT_EOK) { @@ -3855,8 +3782,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -3905,8 +3831,6 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mq->parent.parent))); - rt_schedule(); - return len; } @@ -4018,9 +3942,7 @@ rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg) mq->entry = 0; rt_spin_unlock_irqrestore(&(mq->spinlock), level); - - rt_schedule(); - + return RT_EOK; } diff --git a/src/mempool.c b/src/mempool.c index 28bdb6cf896..9c219427f96 100644 --- a/src/mempool.c +++ b/src/mempool.c @@ -17,6 +17,8 @@ * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to mempool.c * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix spinlock assert + * 2025-06-01 htl5241 remove redundancy rt_schedule() + * fix timer overflow */ #include @@ -327,15 +329,12 @@ void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time) /* enable interrupt */ rt_spin_unlock_irqrestore(&(mp->spinlock), level); - /* do a schedule */ - rt_schedule(); - if (thread->error != RT_EOK) return RT_NULL; if (time > 0) { - time -= rt_tick_get() - before_sleep; + time -= rt_tick_get_delta(before_sleep); if (time < 0) time = 0; } @@ -397,9 +396,6 @@ void rt_mp_free(void *block) { rt_spin_unlock_irqrestore(&(mp->spinlock), level); - /* do a schedule */ - rt_schedule(); - return; } rt_spin_unlock_irqrestore(&(mp->spinlock), level); diff --git a/src/signal.c b/src/signal.c index b33e24220e4..6a7888c755b 100644 --- a/src/signal.c +++ b/src/signal.c @@ -8,6 +8,7 @@ * 2017/10/5 Bernard the first version * 2018/09/17 Jesven fix: in _signal_deliver RT_THREAD_STAT_MASK to RT_THREAD_STAT_SIGNAL_MASK * 2018/11/22 Jesven in smp version rt_hw_context_switch_to add a param + * 2025-06-01 htl5241 remove redundancy rt_schedule() */ #include @@ -118,8 +119,6 @@ static void _signal_deliver(rt_thread_t tid) rt_spin_unlock_irqrestore(&_thread_signal_lock, level); - /* re-schedule */ - rt_schedule(); } else { @@ -165,8 +164,6 @@ static void _signal_deliver(rt_thread_t tid) rt_spin_unlock_irqrestore(&_thread_signal_lock, level); LOG_D("signal stack pointer @ 0x%08x", tid->sp); - /* re-schedule */ - rt_schedule(); } else { @@ -377,9 +374,6 @@ int rt_signal_wait(const rt_sigset_t *set, rt_siginfo_t *si, rt_int32_t timeout) } rt_spin_unlock_irqrestore(&_thread_signal_lock, level); - /* do thread scheduling */ - rt_schedule(); - level = rt_spin_lock_irqsave(&_thread_signal_lock); /* remove signal waiting flag */ diff --git a/src/thread.c b/src/thread.c index ed9dca13b61..ffd290bfa54 100644 --- a/src/thread.c +++ b/src/thread.c @@ -35,6 +35,8 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix thread_exit/detach/delete * fix rt_thread_delay + * 2025-06-01 htl5241 remove redundancy rt_schedule() + * fix timer overflow */ #include @@ -133,8 +135,6 @@ static void _thread_exit(void) rt_exit_critical_safe(critical_level); - /* switch to next task */ - rt_schedule(); } /** @@ -647,9 +647,6 @@ static rt_err_t _thread_sleep(rt_tick_t tick) thread->error = -RT_EINTR; - /* notify a pending rescheduling */ - rt_schedule(); - /* exit critical and do a rescheduling */ rt_exit_critical_safe(critical_level); @@ -692,7 +689,6 @@ RTM_EXPORT(rt_thread_delay); rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) { struct rt_thread *thread; - rt_tick_t cur_tick; rt_base_t critical_level; RT_ASSERT(tick != RT_NULL); @@ -708,13 +704,15 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) /* disable interrupt */ critical_level = rt_enter_critical(); - cur_tick = rt_tick_get(); - if (cur_tick - *tick < inc_tick) + if (rt_tick_get_delta(*tick) < inc_tick) { rt_tick_t left_tick; + rt_tick_t target_tick; + target_tick = *tick + inc_tick; + left_tick = target_tick - rt_tick_get(); - *tick += inc_tick; - left_tick = *tick - cur_tick; + if (left_tick > target_tick) + left_tick = RT_TICK_MAX - left_tick + 1; /* suspend thread */ rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE); @@ -725,8 +723,6 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) rt_exit_critical_safe(critical_level); - rt_schedule(); - /* clear error number of this thread to RT_EOK */ if (thread->error == -RT_ETIMEOUT) { @@ -735,7 +731,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) } else { - *tick = cur_tick; + *tick = rt_tick_get(); rt_exit_critical_safe(critical_level); } diff --git a/src/timer.c b/src/timer.c index ae6da29f760..e8ce986563e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -22,6 +22,8 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-01-25 Shell add RT_TIMER_FLAG_THREAD_TIMER for timer to sync with sched * 2024-05-01 wdfk-prog The rt_timer_check and _soft_timer_check functions are merged + * 2025-06-01 htl5241 remove redundancy + * fix timer overflow */ #include @@ -494,8 +496,6 @@ static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) level = rt_spin_lock_irqsave(lock); - current_tick = rt_tick_get(); - rt_list_init(&list); while (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) @@ -539,8 +539,7 @@ static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) continue; } rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); - if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && - (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) + if ((t->parent.flag & (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_ACTIVATED)) == (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_ACTIVATED)) { /* start it */ t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; @@ -747,7 +746,6 @@ RTM_EXPORT(rt_timer_control); */ void rt_timer_check(void) { - RT_ASSERT(rt_interrupt_get_nest() > 0); #ifdef RT_USING_SMP /* Running on core 0 only */ @@ -762,7 +760,7 @@ void rt_timer_check(void) rt_tick_t next_timeout; ret = _timer_list_next_timeout(_soft_timer_list, &next_timeout); - if ((ret == RT_EOK) && (next_timeout <= rt_tick_get())) + if ((ret == RT_EOK) && ((rt_tick_get() - next_timeout) < RT_TICK_MAX / 2)) { rt_sem_release(&_soft_timer_sem); } From ac4a9b9ad2b18072ec583280a9527f2043b0ac07 Mon Sep 17 00:00:00 2001 From: yueling hu <502966985@qq.com> Date: Wed, 4 Jun 2025 09:59:52 +0800 Subject: [PATCH 2/3] =?UTF-8?q?Revert=20"=E5=88=A0=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E8=B0=83=E5=BA=A6=E4=BB=A3=E7=A0=81=EF=BC=8Cfix=20tim?= =?UTF-8?q?er=20=E6=BA=A2=E5=87=BA"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a6ec1a904e94755663215925d50afa9ed79a0246. --- src/ipc.c | 118 +++++++++++++++++++++++++++++++++++++++++--------- src/mempool.c | 10 +++-- src/signal.c | 8 +++- src/thread.c | 22 ++++++---- src/timer.c | 10 +++-- 5 files changed, 131 insertions(+), 37 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index 05ad3d52ade..35c0146dd33 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -46,8 +46,6 @@ * 2022-10-16 Bernard add prioceiling feature in mutex * 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable - * 2025-06-01 htl5241 remove redundancy rt_schedule() - * fix timer overflow */ #include @@ -628,6 +626,9 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag) /* enable interrupt */ rt_spin_unlock_irqrestore(&(sem->spinlock), level); + /* do schedule */ + rt_schedule(); + if (thread->error != RT_EOK) { return thread->error > 0 ? -thread->error : thread->error; @@ -694,12 +695,16 @@ RTM_EXPORT(rt_sem_trytake); rt_err_t rt_sem_release(rt_sem_t sem) { rt_base_t level; + rt_bool_t need_schedule; + /* parameter check */ RT_ASSERT(sem != RT_NULL); RT_ASSERT(rt_object_get_type(&sem->parent.parent) == RT_Object_Class_Semaphore); RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(sem->parent.parent))); + need_schedule = RT_FALSE; + level = rt_spin_lock_irqsave(&(sem->spinlock)); LOG_D("thread %s releases sem:%s, which value is: %d", @@ -711,6 +716,7 @@ rt_err_t rt_sem_release(rt_sem_t sem) { /* resume the suspended thread */ rt_susp_list_dequeue(&(sem->parent.suspend_thread), RT_EOK); + need_schedule = RT_TRUE; } else { @@ -727,6 +733,10 @@ rt_err_t rt_sem_release(rt_sem_t sem) rt_spin_unlock_irqrestore(&(sem->spinlock), level); + /* resume a thread, re-schedule */ + if (need_schedule == RT_TRUE) + rt_schedule(); + return RT_EOK; } RTM_EXPORT(rt_sem_release); @@ -768,12 +778,14 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) /* set new value */ sem->value = (rt_uint16_t)value; rt_spin_unlock_irqrestore(&(sem->spinlock), level); + rt_schedule(); return RT_EOK; } else if (cmd == RT_IPC_CMD_SET_VLIMIT) { rt_ubase_t max_value; + rt_bool_t need_schedule = RT_FALSE; max_value = (rt_uint16_t)((rt_uintptr_t)arg); if (max_value > RT_SEM_VALUE_MAX || max_value < 1) @@ -788,12 +800,18 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) { /* resume all waiting thread */ rt_susp_list_resume_all(&sem->parent.suspend_thread, RT_ERROR); + need_schedule = RT_TRUE; } } /* set new value */ sem->max_value = max_value; rt_spin_unlock_irqrestore(&(sem->spinlock), level); + if (need_schedule) + { + rt_schedule(); + } + return RT_EOK; } @@ -1427,6 +1445,9 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend rt_spin_unlock(&(mutex->spinlock)); + /* do schedule */ + rt_schedule(); + rt_spin_lock(&(mutex->spinlock)); if (mutex->owner == thread) @@ -1569,10 +1590,14 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) { rt_sched_lock_level_t slvl; struct rt_thread *thread; + rt_bool_t need_schedule; + /* parameter check */ RT_ASSERT(mutex != RT_NULL); RT_ASSERT(rt_object_get_type(&mutex->parent.parent) == RT_Object_Class_Mutex); + need_schedule = RT_FALSE; + /* only thread could release mutex because we need test the ownership */ RT_DEBUG_IN_THREAD_CONTEXT; @@ -1606,7 +1631,8 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) rt_list_remove(&mutex->taken_list); /* whether change the thread priority */ - _check_and_update_prio(thread, mutex); + need_schedule = _check_and_update_prio(thread, mutex); + /* wakeup suspended thread */ if (!rt_list_isempty(&mutex->parent.suspend_thread)) { @@ -1657,6 +1683,8 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) { mutex->priority = 0xff; } + + need_schedule = RT_TRUE; } else { @@ -1679,6 +1707,10 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) rt_spin_unlock(&(mutex->spinlock)); + /* perform a schedule */ + if (need_schedule == RT_TRUE) + rt_schedule(); + return RT_EOK; } RTM_EXPORT(rt_mutex_release); @@ -1936,6 +1968,7 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) rt_sched_lock_level_t slvl; rt_base_t level; rt_base_t status; + rt_bool_t need_schedule; rt_uint32_t need_clear_set = 0; /* parameter check */ @@ -1945,6 +1978,8 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) if (set == 0) return -RT_ERROR; + need_schedule = RT_FALSE; + level = rt_spin_lock_irqsave(&(event->spinlock)); /* set event */ @@ -2004,6 +2039,8 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) rt_sched_thread_ready(thread); thread->error = RT_EOK; + /* need do a scheduling */ + need_schedule = RT_TRUE; } } if (need_clear_set) @@ -2015,6 +2052,10 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set) rt_sched_unlock(slvl); rt_spin_unlock_irqrestore(&(event->spinlock), level); + /* do a schedule */ + if (need_schedule == RT_TRUE) + rt_schedule(); + return RT_EOK; } RTM_EXPORT(rt_event_send); @@ -2154,6 +2195,9 @@ static rt_err_t _rt_event_recv(rt_event_t event, rt_spin_unlock_irqrestore(&(event->spinlock), level); + /* do a schedule */ + rt_schedule(); + if (thread->error != RT_EOK) { /* return error */ @@ -2240,6 +2284,8 @@ rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg) rt_spin_unlock_irqrestore(&(event->spinlock), level); + rt_schedule(); + return RT_EOK; } @@ -2521,7 +2567,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_stamp; + rt_uint32_t tick_delta; rt_err_t ret; /* parameter check */ @@ -2532,7 +2578,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_stamp = 0; + tick_delta = 0; /* get current thread */ thread = rt_thread_self(); @@ -2576,7 +2622,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, if (timeout > 0) { /* get the start tick of timer */ - tick_stamp = rt_tick_get(); + tick_delta = rt_tick_get(); LOG_D("mb_send_wait: start timer of thread:%s", thread->parent.name); @@ -2589,6 +2635,9 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, } rt_spin_unlock_irqrestore(&(mb->spinlock), level); + /* re-schedule */ + rt_schedule(); + /* resume from suspend state */ if (thread->error != RT_EOK) { @@ -2601,7 +2650,8 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - timeout -= rt_tick_get_delta(tick_stamp); + tick_delta = rt_tick_get() - tick_delta; + timeout -= tick_delta; if (timeout < 0) timeout = 0; } @@ -2632,6 +2682,8 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, rt_spin_unlock_irqrestore(&(mb->spinlock), level); + rt_schedule(); + return RT_EOK; } rt_spin_unlock_irqrestore(&(mb->spinlock), level); @@ -2754,6 +2806,8 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) rt_spin_unlock_irqrestore(&(mb->spinlock), level); + rt_schedule(); + return RT_EOK; } rt_spin_unlock_irqrestore(&(mb->spinlock), level); @@ -2792,7 +2846,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_stamp; + rt_uint32_t tick_delta; rt_err_t ret; /* parameter check */ @@ -2803,7 +2857,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_stamp = 0; + tick_delta = 0; /* get current thread */ thread = rt_thread_self(); @@ -2848,7 +2902,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo if (timeout > 0) { /* get the start tick of timer */ - tick_stamp = rt_tick_get(); + tick_delta = rt_tick_get(); LOG_D("mb_recv: start timer of thread:%s", thread->parent.name); @@ -2862,6 +2916,9 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo rt_spin_unlock_irqrestore(&(mb->spinlock), level); + /* re-schedule */ + rt_schedule(); + /* resume from suspend state */ if (thread->error != RT_EOK) { @@ -2873,7 +2930,8 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - timeout -= rt_tick_get_delta(tick_stamp); + tick_delta = rt_tick_get() - tick_delta; + timeout -= tick_delta; if (timeout < 0) timeout = 0; } @@ -2902,6 +2960,8 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mb->parent.parent))); + rt_schedule(); + return RT_EOK; } rt_spin_unlock_irqrestore(&(mb->spinlock), level); @@ -2969,6 +3029,8 @@ rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg) rt_spin_unlock_irqrestore(&(mb->spinlock), level); + rt_schedule(); + return RT_EOK; } @@ -3320,7 +3382,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, { rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_stamp; + rt_uint32_t tick_delta; struct rt_thread *thread; rt_err_t ret; @@ -3340,7 +3402,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, return -RT_ERROR; /* initialize delta tick */ - tick_stamp = 0; + tick_delta = 0; /* get current thread */ thread = rt_thread_self(); @@ -3385,7 +3447,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_stamp = rt_tick_get(); + tick_delta = rt_tick_get(); LOG_D("mq_send_wait: start timer of thread:%s", thread->parent.name); @@ -3399,6 +3461,9 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, rt_spin_unlock_irqrestore(&(mq->spinlock), level); + /* re-schedule */ + rt_schedule(); + /* resume from suspend state */ if (thread->error != RT_EOK) { @@ -3410,7 +3475,8 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - timeout -= rt_tick_get_delta(tick_stamp); + tick_delta = rt_tick_get() - tick_delta; + timeout -= tick_delta; if (timeout < 0) timeout = 0; } @@ -3490,6 +3556,8 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, rt_spin_unlock_irqrestore(&(mq->spinlock), level); + rt_schedule(); + return RT_EOK; } rt_spin_unlock_irqrestore(&(mq->spinlock), level); @@ -3646,6 +3714,8 @@ rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size) rt_spin_unlock_irqrestore(&(mq->spinlock), level); + rt_schedule(); + return RT_EOK; } @@ -3695,7 +3765,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, struct rt_thread *thread; rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_stamp; + rt_uint32_t tick_delta; rt_err_t ret; rt_size_t len; @@ -3711,7 +3781,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_stamp = 0; + tick_delta = 0; /* get current thread */ thread = rt_thread_self(); RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mq->parent.parent))); @@ -3756,7 +3826,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_stamp = rt_tick_get(); + tick_delta = rt_tick_get(); LOG_D("set thread:%s to timer list", thread->parent.name); @@ -3770,6 +3840,9 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, rt_spin_unlock_irqrestore(&(mq->spinlock), level); + /* re-schedule */ + rt_schedule(); + /* recv message */ if (thread->error != RT_EOK) { @@ -3782,7 +3855,8 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - timeout -= rt_tick_get_delta(tick_stamp); + tick_delta = rt_tick_get() - tick_delta; + timeout -= tick_delta; if (timeout < 0) timeout = 0; } @@ -3831,6 +3905,8 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mq->parent.parent))); + rt_schedule(); + return len; } @@ -3942,7 +4018,9 @@ rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg) mq->entry = 0; rt_spin_unlock_irqrestore(&(mq->spinlock), level); - + + rt_schedule(); + return RT_EOK; } diff --git a/src/mempool.c b/src/mempool.c index 9c219427f96..28bdb6cf896 100644 --- a/src/mempool.c +++ b/src/mempool.c @@ -17,8 +17,6 @@ * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to mempool.c * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix spinlock assert - * 2025-06-01 htl5241 remove redundancy rt_schedule() - * fix timer overflow */ #include @@ -329,12 +327,15 @@ void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time) /* enable interrupt */ rt_spin_unlock_irqrestore(&(mp->spinlock), level); + /* do a schedule */ + rt_schedule(); + if (thread->error != RT_EOK) return RT_NULL; if (time > 0) { - time -= rt_tick_get_delta(before_sleep); + time -= rt_tick_get() - before_sleep; if (time < 0) time = 0; } @@ -396,6 +397,9 @@ void rt_mp_free(void *block) { rt_spin_unlock_irqrestore(&(mp->spinlock), level); + /* do a schedule */ + rt_schedule(); + return; } rt_spin_unlock_irqrestore(&(mp->spinlock), level); diff --git a/src/signal.c b/src/signal.c index 6a7888c755b..b33e24220e4 100644 --- a/src/signal.c +++ b/src/signal.c @@ -8,7 +8,6 @@ * 2017/10/5 Bernard the first version * 2018/09/17 Jesven fix: in _signal_deliver RT_THREAD_STAT_MASK to RT_THREAD_STAT_SIGNAL_MASK * 2018/11/22 Jesven in smp version rt_hw_context_switch_to add a param - * 2025-06-01 htl5241 remove redundancy rt_schedule() */ #include @@ -119,6 +118,8 @@ static void _signal_deliver(rt_thread_t tid) rt_spin_unlock_irqrestore(&_thread_signal_lock, level); + /* re-schedule */ + rt_schedule(); } else { @@ -164,6 +165,8 @@ static void _signal_deliver(rt_thread_t tid) rt_spin_unlock_irqrestore(&_thread_signal_lock, level); LOG_D("signal stack pointer @ 0x%08x", tid->sp); + /* re-schedule */ + rt_schedule(); } else { @@ -374,6 +377,9 @@ int rt_signal_wait(const rt_sigset_t *set, rt_siginfo_t *si, rt_int32_t timeout) } rt_spin_unlock_irqrestore(&_thread_signal_lock, level); + /* do thread scheduling */ + rt_schedule(); + level = rt_spin_lock_irqsave(&_thread_signal_lock); /* remove signal waiting flag */ diff --git a/src/thread.c b/src/thread.c index ffd290bfa54..ed9dca13b61 100644 --- a/src/thread.c +++ b/src/thread.c @@ -35,8 +35,6 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix thread_exit/detach/delete * fix rt_thread_delay - * 2025-06-01 htl5241 remove redundancy rt_schedule() - * fix timer overflow */ #include @@ -135,6 +133,8 @@ static void _thread_exit(void) rt_exit_critical_safe(critical_level); + /* switch to next task */ + rt_schedule(); } /** @@ -647,6 +647,9 @@ static rt_err_t _thread_sleep(rt_tick_t tick) thread->error = -RT_EINTR; + /* notify a pending rescheduling */ + rt_schedule(); + /* exit critical and do a rescheduling */ rt_exit_critical_safe(critical_level); @@ -689,6 +692,7 @@ RTM_EXPORT(rt_thread_delay); rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) { struct rt_thread *thread; + rt_tick_t cur_tick; rt_base_t critical_level; RT_ASSERT(tick != RT_NULL); @@ -704,15 +708,13 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) /* disable interrupt */ critical_level = rt_enter_critical(); - if (rt_tick_get_delta(*tick) < inc_tick) + cur_tick = rt_tick_get(); + if (cur_tick - *tick < inc_tick) { rt_tick_t left_tick; - rt_tick_t target_tick; - target_tick = *tick + inc_tick; - left_tick = target_tick - rt_tick_get(); - if (left_tick > target_tick) - left_tick = RT_TICK_MAX - left_tick + 1; + *tick += inc_tick; + left_tick = *tick - cur_tick; /* suspend thread */ rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE); @@ -723,6 +725,8 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) rt_exit_critical_safe(critical_level); + rt_schedule(); + /* clear error number of this thread to RT_EOK */ if (thread->error == -RT_ETIMEOUT) { @@ -731,7 +735,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) } else { - *tick = rt_tick_get(); + *tick = cur_tick; rt_exit_critical_safe(critical_level); } diff --git a/src/timer.c b/src/timer.c index e8ce986563e..ae6da29f760 100644 --- a/src/timer.c +++ b/src/timer.c @@ -22,8 +22,6 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-01-25 Shell add RT_TIMER_FLAG_THREAD_TIMER for timer to sync with sched * 2024-05-01 wdfk-prog The rt_timer_check and _soft_timer_check functions are merged - * 2025-06-01 htl5241 remove redundancy - * fix timer overflow */ #include @@ -496,6 +494,8 @@ static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) level = rt_spin_lock_irqsave(lock); + current_tick = rt_tick_get(); + rt_list_init(&list); while (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) @@ -539,7 +539,8 @@ static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) continue; } rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); - if ((t->parent.flag & (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_ACTIVATED)) == (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_ACTIVATED)) + if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && + (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { /* start it */ t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; @@ -746,6 +747,7 @@ RTM_EXPORT(rt_timer_control); */ void rt_timer_check(void) { + RT_ASSERT(rt_interrupt_get_nest() > 0); #ifdef RT_USING_SMP /* Running on core 0 only */ @@ -760,7 +762,7 @@ void rt_timer_check(void) rt_tick_t next_timeout; ret = _timer_list_next_timeout(_soft_timer_list, &next_timeout); - if ((ret == RT_EOK) && ((rt_tick_get() - next_timeout) < RT_TICK_MAX / 2)) + if ((ret == RT_EOK) && (next_timeout <= rt_tick_get())) { rt_sem_release(&_soft_timer_sem); } From f93c9d86c347c600282e48c95a6aefd1e7ddcf6c Mon Sep 17 00:00:00 2001 From: yueling hu <502966985@qq.com> Date: Wed, 4 Jun 2025 10:27:39 +0800 Subject: [PATCH 3/3] fix timer overflow --- src/ipc.c | 38 ++++++++++++++++++-------------------- src/mempool.c | 3 ++- src/thread.c | 15 +++++++++------ src/timer.c | 6 +++--- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index 35c0146dd33..ca971c49f3b 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -46,6 +46,8 @@ * 2022-10-16 Bernard add prioceiling feature in mutex * 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable + * 2025-06-01 htl5241 fix timer overflow + * */ #include @@ -2567,7 +2569,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; /* parameter check */ @@ -2578,7 +2580,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -2622,7 +2624,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mb_send_wait: start timer of thread:%s", thread->parent.name); @@ -2650,8 +2652,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -2846,7 +2847,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; /* parameter check */ @@ -2857,7 +2858,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -2902,7 +2903,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mb_recv: start timer of thread:%s", thread->parent.name); @@ -2930,8 +2931,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -3382,7 +3382,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, { rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; struct rt_thread *thread; rt_err_t ret; @@ -3402,7 +3402,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, return -RT_ERROR; /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -3447,7 +3447,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mq_send_wait: start timer of thread:%s", thread->parent.name); @@ -3475,8 +3475,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -3765,7 +3764,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, struct rt_thread *thread; rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; rt_size_t len; @@ -3781,7 +3780,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mq->parent.parent))); @@ -3826,7 +3825,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("set thread:%s to timer list", thread->parent.name); @@ -3855,8 +3854,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } diff --git a/src/mempool.c b/src/mempool.c index 28bdb6cf896..3cc7b4517e0 100644 --- a/src/mempool.c +++ b/src/mempool.c @@ -17,6 +17,7 @@ * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to mempool.c * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix spinlock assert + * 2025-06-01 htl5241 fix timer overflow */ #include @@ -335,7 +336,7 @@ void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time) if (time > 0) { - time -= rt_tick_get() - before_sleep; + time -= rt_tick_get_delta(before_sleep); if (time < 0) time = 0; } diff --git a/src/thread.c b/src/thread.c index ed9dca13b61..e7a8362215a 100644 --- a/src/thread.c +++ b/src/thread.c @@ -35,6 +35,8 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix thread_exit/detach/delete * fix rt_thread_delay + * 2025-06-01 htl5241 fix timer overflow + * */ #include @@ -692,7 +694,6 @@ RTM_EXPORT(rt_thread_delay); rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) { struct rt_thread *thread; - rt_tick_t cur_tick; rt_base_t critical_level; RT_ASSERT(tick != RT_NULL); @@ -708,13 +709,15 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) /* disable interrupt */ critical_level = rt_enter_critical(); - cur_tick = rt_tick_get(); - if (cur_tick - *tick < inc_tick) + if (rt_tick_get_delta(*tick) < inc_tick) { rt_tick_t left_tick; + rt_tick_t target_tick; + target_tick = *tick + inc_tick; + left_tick = target_tick - rt_tick_get(); - *tick += inc_tick; - left_tick = *tick - cur_tick; + if (left_tick > target_tick) + left_tick = RT_TICK_MAX - left_tick + 1; /* suspend thread */ rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE); @@ -735,7 +738,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) } else { - *tick = cur_tick; + *tick = rt_tick_get(); rt_exit_critical_safe(critical_level); } diff --git a/src/timer.c b/src/timer.c index ae6da29f760..ee8ef304047 100644 --- a/src/timer.c +++ b/src/timer.c @@ -22,6 +22,8 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-01-25 Shell add RT_TIMER_FLAG_THREAD_TIMER for timer to sync with sched * 2024-05-01 wdfk-prog The rt_timer_check and _soft_timer_check functions are merged + * 2025-06-01 htl5241 remove redundancy + * fix timer overflow */ #include @@ -494,8 +496,6 @@ static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) level = rt_spin_lock_irqsave(lock); - current_tick = rt_tick_get(); - rt_list_init(&list); while (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) @@ -762,7 +762,7 @@ void rt_timer_check(void) rt_tick_t next_timeout; ret = _timer_list_next_timeout(_soft_timer_list, &next_timeout); - if ((ret == RT_EOK) && (next_timeout <= rt_tick_get())) + if ((ret == RT_EOK) && ((rt_tick_get() - next_timeout) < RT_TICK_MAX / 2)) { rt_sem_release(&_soft_timer_sem); }