Skip to content

Commit 1cec4c2

Browse files
KurngsyDailingxiang1
authored andcommitted
fix: [kernel] [thread] Resolve delayed thread wakeup bug when calling suspend repeatedly (#10970)
* Enhance thread suspend function with stricter checks Refactor thread suspension logic to improve clarity and correctness. * Clean up formatting in thread.c Removed unnecessary blank line in thread.c. * Refactor thread suspend state handling Refactor thread suspension logic to improve clarity and maintainability. * Update thread.c * Fix indentation for RT_THREAD_SUSPEND_KILLABLE case
1 parent 8fd59d4 commit 1cec4c2

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

src/thread.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -885,26 +885,27 @@ RTM_EXPORT(rt_thread_control);
885885
#include <lwp_signal.h>
886886
#endif
887887

888-
static void _thread_set_suspend_state(struct rt_thread *thread, int suspend_flag)
888+
/* Convert suspend_flag to corresponding thread suspend state value */
889+
static rt_uint8_t _thread_get_suspend_state(int suspend_flag)
889890
{
890-
rt_uint8_t stat = RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
891-
892-
RT_ASSERT(thread != RT_NULL);
893891
switch (suspend_flag)
894892
{
895893
case RT_INTERRUPTIBLE:
896-
stat = RT_THREAD_SUSPEND_INTERRUPTIBLE;
897-
break;
894+
return RT_THREAD_SUSPEND_INTERRUPTIBLE;
898895
case RT_KILLABLE:
899-
stat = RT_THREAD_SUSPEND_KILLABLE;
900-
break;
896+
return RT_THREAD_SUSPEND_KILLABLE;
901897
case RT_UNINTERRUPTIBLE:
902-
stat = RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
903-
break;
904898
default:
905-
RT_ASSERT(0);
906-
break;
899+
return RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
907900
}
901+
}
902+
903+
static void _thread_set_suspend_state(struct rt_thread *thread, int suspend_flag)
904+
{
905+
rt_uint8_t stat;
906+
907+
RT_ASSERT(thread != RT_NULL);
908+
stat = _thread_get_suspend_state(suspend_flag);
908909
RT_SCHED_CTX(thread).stat = stat | (RT_SCHED_CTX(thread).stat & ~RT_THREAD_STAT_MASK);
909910
}
910911

@@ -943,20 +944,31 @@ rt_err_t rt_thread_suspend_to_list(rt_thread_t thread, rt_list_t *susp_list, int
943944
RT_ASSERT(thread != RT_NULL);
944945
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
945946

946-
LOG_D("thread suspend: %s", thread->parent.name);
947+
LOG_D("thread suspend: %s", thread->parent.name);
947948

948949
rt_sched_lock(&slvl);
949950

950951
stat = rt_sched_thread_get_stat(thread);
951-
if (stat == RT_THREAD_SUSPEND)
952+
if (stat & RT_THREAD_SUSPEND_MASK)
952953
{
954+
if (RT_SCHED_CTX(thread).sched_flag_ttmr_set == 1)
955+
{
956+
/* The new suspend operation will halt the tick timer. */
957+
LOG_D("Thread [%s]'s timer has been halted.\n", thread->parent.name);
958+
rt_sched_thread_timer_stop(thread);
959+
}
960+
/* Upgrade suspend state if new state is stricter */
961+
if (stat < _thread_get_suspend_state(suspend_flag))
962+
{
963+
_thread_set_suspend_state(thread, suspend_flag);
964+
}
953965
rt_sched_unlock(slvl);
954-
/* Already suspended, just set status to success. */
966+
/* Already suspended, just set the status to success. */
955967
return RT_EOK;
956968
}
957969
else if ((stat != RT_THREAD_READY) && (stat != RT_THREAD_RUNNING))
958970
{
959-
LOG_D("thread suspend: thread disorder, 0x%2x", RT_SCHED_CTX(thread).stat);
971+
LOG_W("thread suspend: thread disorder, 0x%02x", RT_SCHED_CTX(thread).stat);
960972
rt_sched_unlock(slvl);
961973
return -RT_ERROR;
962974
}

0 commit comments

Comments
 (0)