RT-Thread内核之线程调度(四)

以下为线程部分的源码分析:

extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];

extern struct rt_thread *rt_current_thread;

extern rt_list_t rt_thread_defunct;

/*******************************************************************************************

** 函数名称: rt_thread_exit

** 函数功能: 线程退出

** 入口参数: 无

** 返 回 值: 无

** 调    用: _rt_thread_init

*******************************************************************************************/

static void rt_thread_exit(void)

{

struct rt_thread* thread;

register rt_base_t level;

/** 获取当前正在运行的线程 */

thread = rt_current_thread;

/** 禁止全局中断 */

level = rt_hw_interrupt_disable();

/** 从调度器中移除该线程 */

rt_schedule_remove_thread(thread);

/** 将线程的状态设置为CLOSE状态 */

thread->stat = RT_THREAD_CLOSE;

/** 注销线程内置的定时器 */

rt_timer_detach(&thread->thread_timer);

/** 如果对象为系统对象并且线程不含cleanup方法,注销该线程 */

if ((rt_object_is_systemobject((rt_object_t)thread) ==
RT_TRUE) &&

thread->cleanup == RT_NULL) {

rt_object_detach((rt_object_t)thread);

} else { /** 否则将该线程链接到僵尸线程链表中 */

rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));

}

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

/** 触发调度 */

rt_schedule();

}

/*******************************************************************************************

** 函数名称: _rt_thread_init

** 函数功能: 初始化线程实例

** 入口参数: thread 线程对象句柄

**          name 线程的名字

**          entry 线程的入口函数

**          parameter 附加参数

**          stack_start 栈底指针

**          stack_size 栈的大小

**          priority 线程的优先级

**          tick 线程的初始滴答数(能运行的时间片值)

** 返 回 值: 成功返回RT_EOK

** 调    用: rt_thread_init

*******************************************************************************************/

static rt_err_t _rt_thread_init(struct rt_thread* thread,

const char* name,

void (*entry)(void *parameter),

void * parameter,

void * stack_start,

rt_uint32_t stack_size,

rt_uint8_t  priority,

rt_uint32_t tick)

{

/** 初始化线程链表节点成员 */

rt_list_init(&(thread->tlist));

thread->entry = (void *)entry;

thread->parameter = parameter;

thread->stack_addr = stack_start;

thread->stack_size = (rt_uint16_t)stack_size;

/** 初始化线程的栈 */

rt_memset(thread->stack_addr, ‘#‘, thread->stack_size);

thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,

(void *)((char *)thread->stack_addr + thread->stack_size - 4),

(void *)rt_thread_exit);

RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);

thread->init_priority    = priority;

thread->current_priority = priority;

thread->init_tick      = tick;

thread->remaining_tick = tick;

thread->error = RT_EOK;

/** 创建线程时,线程处于INIT状态 */

thread->stat  = RT_THREAD_INIT;

thread->cleanup   = 0;

thread->user_data = 0;

/** 初始化线程内嵌的定时器 */

rt_timer_init(&(thread->thread_timer),

thread->name,

rt_thread_timeout,

thread,

0,

RT_TIMER_FLAG_ONE_SHOT);

return RT_EOK;

}

/*******************************************************************************************

** 函数名称: rt_thread_init

** 函数功能: 静态初始化线程实例

** 入口参数: thread 线程对象句柄

**    name 线程的名字

**    entry
线程的入口函数

**    parameter
附加参数

**    stack_start 栈底指针

**    stack_size 栈的大小

**    priority 线程的优先级

**    tick
线程的初始滴答数(能运行的时间片值)

** 返 回 值: 成功返回RT_EOK

** 调    用: rt_thread_init

*******************************************************************************************/

rt_err_t rt_thread_init(struct rt_thread *thread,

const char       *name,

void (*entry)(void *parameter),

void* parameter,

void* stack_start,

rt_uint32_t stack_size,

rt_uint8_t priority,

rt_uint32_t tick)

{

/** 参数检查 */

RT_ASSERT(thread !=
RT_NULL);

RT_ASSERT(stack_start !=
RT_NULL);

/** 初始化线程内嵌的对象结构 */

rt_object_init((rt_object_t)thread,
RT_Object_Class_Thread, name);

/** 初始化线程实例 */

return _rt_thread_init(thread,

name,

entry,

parameter,

stack_start,

stack_size,

priority,

tick);

}

RTM_EXPORT(rt_thread_init);

/*******************************************************************************************

** 函数名称: rt_thread_init

** 函数功能: 返回当前正在运行的线程对象句柄

** 入口参数: 无

** 返 回 值: 线程对象句柄

** 调    用: rt_thread_init

*******************************************************************************************/

rt_thread_t rt_thread_self(void)

{

return rt_current_thread;

}

RTM_EXPORT(rt_thread_self);

/*******************************************************************************************

** 函数名称: rt_thread_startup

** 函数功能: 启动线程将线程放入系统就绪队列中

** 入口参数: thread 线程对象句柄

** 返 回 值: 返回RT_EOK

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_startup(rt_thread_t thread)

{

/** 参数检查 */

RT_ASSERT(thread !=RT_NULL);

RT_ASSERT(thread->stat ==
RT_THREAD_INIT);

/** 设置线程的当前优先级 */

thread->current_priority = thread->init_priority;

/** 计算优先级属性 */

#if RT_THREAD_PRIORITY_MAX > 32

thread->number      = thread->current_priority >> 3;            /* 5bit */

thread->number_mask = 1L << thread->number;

thread->high_mask   = 1L << (thread->current_priority & 0x07);  /* 3bit */

#else

thread->number_mask = 1L << thread->current_priority;

#endif

RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",

thread->name, thread->init_priority));

/** 设置线程的状态为挂起状态 */

thread->stat = RT_THREAD_SUSPEND;

/** 恢复线程 */

rt_thread_resume(thread);

/** 如果系统已经运行 */

if (rt_thread_self() != RT_NULL) {

rt_schedule(); /** 调度 */

}

return RT_EOK;

}

RTM_EXPORT(rt_thread_startup);

/*******************************************************************************************

** 函数名称: rt_thread_detach

** 函数功能: 注销线程

** 入口参数: thread 线程对象句柄

** 返 回 值: 返回RT_EOK

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_detach(rt_thread_t thread)

{

rt_base_t lock;

/** 参数检查 */

RT_ASSERT(thread !=
RT_NULL);

/** 从调度队列中移除该线程 */

rt_schedule_remove_thread(thread);

/** 注销该线程内嵌的定时器 */

rt_timer_detach(&(thread->thread_timer));

/** 将线程的状态设置为CLOSE状态 */

thread->stat = RT_THREAD_CLOSE;

/** 注销线程内嵌的对象结构 */

rt_object_detach((rt_object_t)thread);

/** 如果线程含cleanup方法 */

if (thread->cleanup != RT_NULL) {

/** 禁止全局中断 */

lock = rt_hw_interrupt_disable();

/** 将该线程插入到僵尸链表中 */

rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));

/** 使能全局中断 */

rt_hw_interrupt_enable(lock);

}

return RT_EOK;

}

RTM_EXPORT(rt_thread_detach);

#ifdef RT_USING_HEAP

/*******************************************************************************************

** 函数名称: rt_thread_create

** 函数功能: 动态的创建线程

** 入口参数: name 线程的名字

**     entry
线程的入口

**     parameter附加参数

**     stack_size线程栈的大小

**     priority线程的优先级

**     tick
线程的初始化滴答数

** 返 回 值: 线程对象句柄

** 调    用:

*******************************************************************************************/

rt_thread_t rt_thread_create(const char *name,

void (*entry)(void *parameter),

void       *parameter,

rt_uint32_t stack_size,

rt_uint8_t  priority,

rt_uint32_t tick)

{

struct rt_thread *thread;

void *stack_start;

/** 分配线程对象 */

thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread, name);

if (thread == RT_NULL)

return RT_NULL;

/** 分配线程的栈 */

stack_start = (void *)RT_KERNEL_MALLOC(stack_size);

if (stack_start == RT_NULL) {

rt_object_delete((rt_object_t)thread);

return RT_NULL;

}

/** 初始化线程实例 */

_rt_thread_init(thread,

name,

entry,

parameter,

stack_start,

stack_size,

priority,

tick);

return thread;

}

RTM_EXPORT(rt_thread_create);

/*******************************************************************************************

** 函数名称: rt_thread_delete

** 函数功能: 释放一个线程

** 入口参数: thread 线程的句柄

** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_delete(rt_thread_t thread)

{

rt_base_t lock;

/** 参数检查 */

RT_ASSERT(thread != RT_NULL);

/** 从调度队列中移除线程 */

rt_schedule_remove_thread(thread);

/** 注销线程内嵌的定时器对象 */

rt_timer_detach(&(thread->thread_timer));

/** 线程的状态设置为CLOSE */

thread->stat = RT_THREAD_CLOSE;

/** 禁止全局中断 */

lock = rt_hw_interrupt_disable();

/** 将线程放入僵尸链表中 */

rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));

/** 将线程放入僵尸链表中 */

rt_hw_interrupt_enable(lock);

return RT_EOK;

}

RTM_EXPORT(rt_thread_delete);

#endif

/*******************************************************************************************

** 函数名称: rt_thread_yield

** 函数功能: 线程放弃处理器

** 入口参数: 无

** 返 回 值: RT_EOK

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_yield(void)

{

register rt_base_t level;

struct rt_thread *thread;

/** 禁止全局中断 */

level = rt_hw_interrupt_disable();

/** 获取当前线程对象指针 */

thread = rt_current_thread;

/** 如果该线程处于就绪状态并且同一优先级链表中还有其他线程 */

if (thread->stat == RT_THREAD_READY &&

thread->tlist.next != thread->tlist.prev) {

/** 将该线程从就绪链表中移除 */

rt_list_remove(&(thread->tlist));

/** 将线程放到就绪链表的末尾 */

rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),

&(thread->tlist));

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

/** 调度 */

rt_schedule();

return RT_EOK;

}

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

return RT_EOK;

}

RTM_EXPORT(rt_thread_yield);

/*******************************************************************************************

** 函数名称: rt_thread_sleep

** 函数功能: 线程睡眠tick个时钟滴答

** 入口参数: tick 线程睡眠的滴答数

** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_sleep(rt_tick_t tick)

{

register rt_base_t temp;

struct rt_thread *thread;

/** 禁止全局中断 */

temp = rt_hw_interrupt_disable();

/** 获取当前线程 */

thread = rt_current_thread;

RT_ASSERT(thread !=
RT_NULL);

/** 挂起当前线程 */

rt_thread_suspend(thread);

/** 复位线程内嵌的定时器并启动定时器 */

rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);

rt_timer_start(&(thread->thread_timer));

/** 使能全局中断 */

rt_hw_interrupt_enable(temp);

/** 调度 */

rt_schedule();

/** 如果线程是因为超时唤醒 */

if (thread->error == -RT_ETIMEOUT)

thread->error = RT_EOK;

return RT_EOK;

}

/*******************************************************************************************

** 函数名称: rt_thread_delay

** 函数功能: 线程睡眠tick个时钟滴答

** 入口参数: tick 线程睡眠的滴答数

** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_delay(rt_tick_t tick)

{

return rt_thread_sleep(tick);

}

RTM_EXPORT(rt_thread_delay);

/*******************************************************************************************

** 函数名称: rt_thread_control

** 函数功能: 给线程发命令

** 入口参数: thread 线程对象句柄

**     cmd
命令

**     arg
附加参数

** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void *arg)

{

register rt_base_t temp;

/** 参数检查 */

RT_ASSERT(thread !=
RT_NULL);

switch (cmd) {

case RT_THREAD_CTRL_CHANGE_PRIORITY:/** 改变线程的优先级 */

/** 禁止全局中断 */

temp = rt_hw_interrupt_disable();

/** 如果线程为就绪状态 */

if (thread->stat == RT_THREAD_READY) {

/** 将线程从就绪队列中移除 */

rt_schedule_remove_thread(thread);

/** 改变线程的优先级 */

thread->current_priority = *(rt_uint8_t *)arg;

/** 重新计算线程的优先级属性 */

#if RT_THREAD_PRIORITY_MAX > 32

thread->number      = thread->current_priority >> 3;            /* 5bit */

thread->number_mask = 1 << thread->number;

thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */

#else

thread->number_mask = 1 << thread->current_priority;

#endif

/** 将线程以新的优先级插入到就绪队列中 */

rt_schedule_insert_thread(thread);

} else {

/** 线程的为非就绪状态 */

thread->current_priority = *(rt_uint8_t *)arg;

#if RT_THREAD_PRIORITY_MAX > 32

thread->number      = thread->current_priority >> 3;            /* 5bit */

thread->number_mask = 1 << thread->number;

thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */

#else

thread->number_mask = 1 << thread->current_priority;

#endif

}

/** 使能全局中断 */

rt_hw_interrupt_enable(temp);

break;

case RT_THREAD_CTRL_STARTUP:/** 启动线程 */

return rt_thread_startup(thread);

#ifdef RT_USING_HEAP

case RT_THREAD_CTRL_CLOSE:/** 释放线程 */

return rt_thread_delete(thread);

#endif

default:

break;

}

return RT_EOK;

}

RTM_EXPORT(rt_thread_control);

/*******************************************************************************************

** 函数名称: rt_thread_suspend

** 函数功能: 挂起线程

** 入口参数: thread 线程对象句柄

** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_suspend(rt_thread_t thread)

{

register rt_base_t temp;

/** 参数检查 */

RT_ASSERT(thread !=
RT_NULL);

RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend:  %s\n", thread->name));

/** 如果线程的状态为非就绪状态,出错 */

if (thread->stat != RT_THREAD_READY) {

RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, %d\n",

thread->stat));

return -RT_ERROR;

}

/** 禁止全局中断 */

temp = rt_hw_interrupt_disable();

/** 设置线程的状态为挂起状态 */

thread->stat = RT_THREAD_SUSPEND;

/** 将线程从就绪队列中移除 */

rt_schedule_remove_thread(thread);

/** 使能全局中断 */

rt_hw_interrupt_enable(temp);

return RT_EOK;

}

RTM_EXPORT(rt_thread_suspend);

/*******************************************************************************************

** 函数名称: rt_thread_resume

** 函数功能: 恢复线程

** 入口参数: thread 线程对象句柄

** 返 回 值: 成功返回RT_EOK;失败返回-RT_ERROR

** 调    用:

*******************************************************************************************/

rt_err_t rt_thread_resume(rt_thread_t thread)

{

register rt_base_t temp;

/** 检查参数 */

RT_ASSERT(thread !=
RT_NULL);

RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume:  %s\n", thread->name));

/** 如果线程的状态非挂起状态,出错 */

if (thread->stat != RT_THREAD_SUSPEND) {

RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n",

thread->stat));

return -RT_ERROR;

}

/** 禁止全局中断 */

temp = rt_hw_interrupt_disable();

/** 将线程从挂起链表中移除 */

rt_list_remove(&(thread->tlist));

/** 停止定时器 */

rt_timer_stop(&thread->thread_timer);

/** 使能全局中断 */

rt_hw_interrupt_enable(temp);

/** 将线程插入就绪队列中 */

rt_schedule_insert_thread(thread);

return RT_EOK;

}

RTM_EXPORT(rt_thread_resume);

/*******************************************************************************************

** 函数名称: rt_thread_timeout

** 函数功能: 线程定时器超时时的处理函数

** 入口参数: parameter 定时器的附加参数

** 返 回 值: 无

** 调    用:

*******************************************************************************************/

void rt_thread_timeout(void *parameter)

{

struct rt_thread *thread;

thread = (struct rt_thread *)parameter;

/** 参数检查 */

RT_ASSERT(thread != RT_NULL);

RT_ASSERT(thread->stat == RT_THREAD_SUSPEND);

/** 超时 */

thread->error = -RT_ETIMEOUT;

/** 从挂起队列中移除 */

rt_list_remove(&(thread->tlist));

/** 插入到就绪队列中 */

rt_schedule_insert_thread(thread);

/** 调度 */

rt_schedule();

}

RTM_EXPORT(rt_thread_timeout);

/********************************************************************************************* 函数名称: rt_thread_find

** 函数功能: 由名字找到对应的线程

** 入口参数: 线程对象句柄

** 返 回 值: 无

** 调    用:

*******************************************************************************************/

rt_thread_t rt_thread_find(char *name)

{

struct rt_object_information *information;

struct rt_object *object;

struct rt_list_node *node;

extern struct rt_object_information rt_object_container[];

/** 进入临界区 */

if (rt_thread_self() != RT_NULL)

rt_enter_critical();

information = &rt_object_container[RT_Object_Class_Thread];

for (node = information->object_list.next; node != &(information->object_list); node = node->next) {

object = rt_list_entry(node, struct rt_object, list);

if (rt_strncmp(object->name, name,
RT_NAME_MAX) == 0) {

/** 找到对象后,退出临界区 */

if (rt_thread_self() !=
RT_NULL)

rt_exit_critical();

return (rt_thread_t)object;

}

}

/** 退出临界区 */

if (rt_thread_self() != RT_NULL)

rt_exit_critical();

/** 没有找到,返回NULL */

return RT_NULL;

}

RTM_EXPORT(rt_thread_find);

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 22:42:43

RT-Thread内核之线程调度(四)的相关文章

RT Thread学习历程(1):串口乱码问题

因为学习实时系统,最近接触到RT Thread. 把RT Thread官网上的示例代码烧录到STM32的板子上之后,在串口软件上接收到的全是乱码,一开始以为是串口软件的问题,换了2个软件之后情况都一样,最后发现是晶振的问题,我用的是STM32F407VGT6,晶振要设为8MHz,代码相应的设置晶振的部分也要修改.

Linux内核分析(四)----进程管理|网络子系统|虚拟文件系统|驱动简介

Linux内核分析(四) 两天没有更新了,上次博文我们分析了linux的内存管理子系统,本来我不想对接下来的进程管理子系统.网络子系统.虚拟文件系统在这个阶段进行分析的,但是为了让大家对内核有个整体的把握,今天还是简单的介绍一下剩余的几个子系统,我们对这几个子系统的分析,只要了解其作用和部分内容即可,不必深究,等我们写上几个驱动,到时候按照驱动再来分析这几个子系统我们就清晰多了. 在http://www.cnblogs.com/wrjvszq/p/4257164.html一文我们提到过linux

Linux内核设计基础(四)之虚拟文件系统

先来看一下写文件函数write的执行过程: ret = write(fd, buf, len); write适用于各种文件系统,它首先执行sys_write(),而正是这个sys_write()进行实际文件系统类型的判别并执行该类型文件系统下的写操作.我们可以看出在多种多样的文件系统上抽象出了一个通用接口性质的虚拟文件系统. 我们这里非常关心Linux 2.6是如何去实现VFS的.先来看一下VFS中的四个主要的对象类型: 超级块对象,它代表一个具体的已安装文件系统. 索引节点对象,它代表一个具体

十天学Linux内核之第四天---如何处理输入输出操作

原文:十天学Linux内核之第四天---如何处理输入输出操作 真的是悲喜交加呀,本来这个寒假早上8点都去练车,两个小时之后再来实验室陪伴Linux内核,但是今天教练说没名额考试了,好纠结,不过想想就可以睡懒觉了,哈哈,自从大三寒假以来还没睡过懒觉呢,现在也有更多的时间来分享自己学习Linux内核的感受,前几天觉得就是自己也有些不懂的,相信大家看了也是很模糊,以后我会标志出来自己不懂的,希望大神们指教,也希望大家多多指点,共同攻克Linux内核,今天将讲到处理器是如何与其它设备进行交互的,内核又是

java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // TODO Auto-generated method stub while(true){ if(ticket > 0){//当线程0被调起的时候,当执行到这条判断语句的时候,线程1被调起抢了CPU资源,线程0进入冻结状态. try { Thread.sleep(100);//中断当前活跃的线程,或者

CodeIgniter3 内核学习笔记四@Benchmark.php

自动启用的系统基准测试类,位于core/Benchmark.php 用于计算两个标记点之间的时间差,基准测试总是在框架被调用的那一刻开始,在输出类向浏览器发送最终的视图之前结束. 这样可以显示出整个系统执行的精确时间 Benchmark.php CodeIgniter3 内核学习笔记四@Benchmark.php

Linux内核分析第四章 读书笔记

Linux内核分析第四章 读书笔记 第一部分--进程调度 进程调度:操作系统规定下的进程选取模式 面临问题:多任务选择问题 多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这会产生多个进程在同时运行的幻觉,在多处理器机器上,这会使多个进程在不同的处理机上真正同时.并行地运行.无论在单处理器或者多处理器机器上,多任务操作系统都能使多个进程处于堵塞或者睡眠状态,也就是说,实际上不被投入执行,直到工作确实就绪. 多任务系统可以划分为两类:非抢占式多任务和抢占式多任务.Linu

linux内核分析第二四学习报告

学生  黎静 课程内容 计算机三大法宝 • 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: • 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: • 中断,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序. 一.函数调用堆栈 1.堆栈 堆栈式C语言程序运行时必须的一个记录调用路径和参数的空间.包括: 函数调用框架 传递参数 保存返回地址(如eax)

RT-thread内核之线程调度算法分析

一个操作系统如果只是具备了高优先级任务能够“立即”获得处理器并得到执行的特点,那么它仍然不算是实时操作系统.因为这个查找最高优先级线程的过程决定了调度时间是否具有确定性,例如一个包含n个就绪任务的系统中,如果仅仅从头找到尾,那么这个时间将直接和n相关,而下一个就绪线程抉择时间的长短将会极大的影响系统的实时性.当所有就绪线程都链接在它们对应的优先级队列中时,抉择过程就将演变为在优先级数组中寻找具有最高优先级线程的非空链表. RT-Thread内核中采用了基于位图(bitmap)的优先级算法(时间复