فهرست منبع

Merge pull request #336 from grissiom/fix-idle

kernel/idle: fix rt_thread_idle_excute in high optimization level
Bernard Xiong 10 سال پیش
والد
کامیت
ddd51caf62
1فایلهای تغییر یافته به همراه16 افزوده شده و 2 حذف شده
  1. 16 2
      src/idle.c

+ 16 - 2
src/idle.c

@@ -67,6 +67,20 @@ void rt_thread_idle_sethook(void (*hook)(void))
 /*@}*/
 #endif
 
+/* Return whether there is defunctional thread to be deleted. */
+rt_inline int _has_defunct_thread(void)
+{
+    /* The rt_list_isempty has prototype of "int rt_list_isempty(const rt_list_t *l)".
+     * So the compiler has a good reason that the rt_thread_defunct list does
+     * not change within rt_thread_idle_excute thus optimize the "while" loop
+     * into a "if".
+     *
+     * So add the volatile qualifier here. */
+    const volatile rt_list_t *l = (const volatile rt_list_t*)&rt_thread_defunct;
+
+    return l->next != l;
+}
+
 /**
  * @ingroup Thread
  *
@@ -76,7 +90,7 @@ void rt_thread_idle_excute(void)
 {
     /* Loop until there is no dead thread. So one call to rt_thread_idle_excute
      * will do all the cleanups. */
-    while (!rt_list_isempty(&rt_thread_defunct))
+    while (_has_defunct_thread())
     {
         rt_base_t lock;
         rt_thread_t thread;
@@ -89,7 +103,7 @@ void rt_thread_idle_excute(void)
         lock = rt_hw_interrupt_disable();
 
         /* re-check whether list is empty */
-        if (!rt_list_isempty(&rt_thread_defunct))
+        if (_has_defunct_thread())
         {
             /* get defunct thread */
             thread = rt_list_entry(rt_thread_defunct.next,