目录
4.1、2次调用_has_defunct_thread()解析
5、rt_thread_idle_gethandler()函数
在 idle 线程内部不允许执行线程挂起操作,所以 Flash 、网络等后端可能无法基于 idle 线程使用。
初始化空闲线程。
- void rt_thread_idle_init(void)
- {
- /* 初始化空闲线程 */
- rt_thread_init(&idle,
- "idle",
- rt_thread_idle_entry,
- RT_NULL,
- &rt_thread_stack[0],
- sizeof(rt_thread_stack),
- RT_THREAD_PRIORITY_MAX - 1,
- 32);
-
- rt_thread_startup(&idle); //启动线程
- }
空闲线程入口函数。
1)如果存在空闲钩子函数,将调用钩子函数。
2)*调用rt_thread_idle_excute()函数执行空闲时做的一些后台工作
3)*调用rt_system_power_manager()函数进行电源管理,如低功耗。
- static void rt_thread_idle_entry(void *parameter)
- {
- while (1)
- {
-
- /* 如果存在空闲钩子函数,将调用钩子函数 */
- #ifdef RT_USING_IDLE_HOOK
- rt_size_t i;
-
- for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
- {
- if (idle_hook_list[i] != RT_NULL)
- {
- idle_hook_list[i]();
- }
- }
- #endif
-
- rt_thread_idle_excute(); //空闲时做的一些后台工作
- #ifdef RT_USING_PM
- rt_system_power_manager(); //电源管理
- #endif
- }
- }
rt_list_isempty的原型为“int rt_list_isempty(const rt_list_t *l)”。因此,编译器有充分的理由在rt_thread_idle_excute中不更改rt_thread_defunct列表,从而将“while”循环优化为“if”循环。所以在这里添加volatile限定符。
- rt_inline int _has_defunct_thread(void)
- {
- const volatile rt_list_t *l = (const volatile rt_list_t *)&rt_thread_defunct;
-
- return l->next != l;
- }
进行以下循环,直至无僵尸线程:
1)获取僵尸线程,并从僵尸链表中移除
2)调用线程清理函数
3)如果是静态线程对象,脱离对象后直接返回
4)如果是动态线程对象,释放动态线程栈内存,删除动态线程对象,然后继续循环
- void rt_thread_idle_excute(void)
- {
- while (_has_defunct_thread())
- {
- rt_base_t lock;
- rt_thread_t thread;
- #ifdef RT_USING_MODULE
- struct rt_dlmodule *module = RT_NULL;
- #endif
- RT_DEBUG_NOT_IN_INTERRUPT;
-
- lock = rt_hw_interrupt_disable(); //关中断
-
- /* 重新检查僵尸链表是否为空 */
- if (_has_defunct_thread())
- {
- /* 获取僵尸线程 */
- thread = rt_list_entry(rt_thread_defunct.next,
- struct rt_thread,
- tlist);
- #ifdef RT_USING_MODULE
- module = (struct rt_dlmodule*)thread->module_id;
- if (module)
- {
- dlmodule_destroy(module);
- }
- #endif
- /* 从僵尸链表中移除 */
- rt_list_remove(&(thread->tlist));
-
- rt_enter_critical(); //进入临界区
-
- /* 调用线程清理函数 */
- if (thread->cleanup != RT_NULL)
- thread->cleanup(thread);
-
- #ifdef RT_USING_SIGNALS
- rt_thread_free_sig(thread);
- #endif
-
- /* 如果是系统对象 */
- if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
- {
- rt_object_detach((rt_object_t)thread); //脱离对象
-
- rt_exit_critical(); //退出临界区
-
- rt_hw_interrupt_enable(lock); //开中断
-
- return;
- }
-
- rt_exit_critical(); //退出临界区
- }
- else
- {
- rt_hw_interrupt_enable(lock); //开中断
-
- return;
- }
-
- rt_hw_interrupt_enable(lock); //开中断
-
- #ifdef RT_USING_HEAP
- RT_KERNEL_FREE(thread->stack_addr); //释放动态线程栈内存
- rt_object_delete((rt_object_t)thread); //删除动态线程对象
- #endif
- }
- }
第一处while (_has_defunct_thread()),用于循环处理所有僵尸线程
第二处if (_has_defunct_thread()),用于确认存在僵尸线程。在第一处和第二处之间未关中断前,可能因为调度,僵尸线程被其他线程从僵尸链表中移除.所以需要二次确认。
为了实时性,在循环期间可以被抢占。
返回空闲线程控制块。
- rt_thread_t rt_thread_idle_gethandler(void)
- {
- return (rt_thread_t)(&idle);
- }
设置空闲钩子函数。最多可有RT_IDEL_HOOK_LIST_SIZE个空闲钩子函数。
- rt_err_t rt_thread_idle_sethook(void (*hook)(void))
- {
- rt_size_t i;
- rt_base_t level;
- rt_err_t ret = -RT_EFULL;
-
- level = rt_hw_interrupt_disable(); //关中断
-
- /* 将钩子函数放入钩子函数数组中 */
- for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
- {
- if (idle_hook_list[i] == RT_NULL)
- {
- idle_hook_list[i] = hook;
- ret = RT_EOK;
- break;
- }
- }
-
- rt_hw_interrupt_enable(level); //开中断
-
- return ret;
- }
从空闲钩子函数数组删除指定空闲钩子函数。
- rt_err_t rt_thread_idle_delhook(void (*hook)(void))
- {
- rt_size_t i;
- rt_base_t level;
- rt_err_t ret = -RT_ENOSYS;
-
- level = rt_hw_interrupt_disable(); //关中断
-
- /* 从空闲钩子函数数组删除指定空闲钩子函数 */
- for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
- {
- if (idle_hook_list[i] == hook)
- {
- idle_hook_list[i] = RT_NULL;
- ret = RT_EOK;
- break;
- }
- }
-
- rt_hw_interrupt_enable(level); //开中断
-
- return ret;
- }