Skip to content

Commit 29e5f61

Browse files
wdfk-progRbb666
authored andcommitted
fix[src][thread]: add defensive check for idle thread suspension
1 parent 8be4b05 commit 29e5f61

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

include/rtthread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ rt_err_t rt_thread_idle_sethook(void (*hook)(void));
218218
rt_err_t rt_thread_idle_delhook(void (*hook)(void));
219219
#endif /* defined(RT_USING_HOOK) || defined(RT_USING_IDLE_HOOK) */
220220
rt_thread_t rt_thread_idle_gethandler(void);
221+
rt_bool_t rt_thread_is_idle_thread(rt_thread_t thread);
221222

222223
/*
223224
* schedule service

src/idle.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,42 @@ rt_thread_t rt_thread_idle_gethandler(void)
212212
return (rt_thread_t)(&idle_thread[id]);
213213
}
214214

215+
/**
216+
* @brief Check whether the specified thread is one of the system idle threads.
217+
*
218+
* @details
219+
* RT-Thread creates an idle thread for each CPU. These idle threads are special
220+
* scheduler-owned threads that act as the fallback runnable threads when no
221+
* other ready thread exists.
222+
*
223+
* This helper is mainly used for defensive checks in code paths that may block
224+
* or suspend a thread, because an idle thread must never enter a blocking or
225+
* suspended state. Suspending an idle thread may leave the system with no ready
226+
* thread and break scheduling.
227+
*
228+
* @param thread The thread to test.
229+
*
230+
* @return RT_TRUE if @p thread is an idle thread of any CPU; otherwise RT_FALSE.
231+
*
232+
* @note
233+
* - In SMP configurations, there is one idle thread per CPU, so this function
234+
* checks against all idle thread objects.
235+
* - Passing RT_NULL returns RT_FALSE.
236+
*/
237+
rt_bool_t rt_thread_is_idle_thread(rt_thread_t thread)
238+
{
239+
rt_ubase_t i;
240+
241+
if (thread != RT_NULL)
242+
{
243+
for (i = 0; i < _CPUS_NR; i++)
244+
{
245+
if (thread == &idle_thread[i])
246+
return RT_TRUE;
247+
}
248+
}
249+
250+
return RT_FALSE;
251+
}
252+
215253
/** @} group_thread_management */

src/thread.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ rt_err_t rt_thread_suspend_to_list(rt_thread_t thread, rt_list_t *susp_list, int
943943
/* parameter check */
944944
RT_ASSERT(thread != RT_NULL);
945945
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
946+
RT_ASSERT(!rt_thread_is_idle_thread(thread));
946947

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

0 commit comments

Comments
 (0)