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

scheduler.c分析

/**

* 中断嵌套的层数

*/

extern volatile rt_uint8_t rt_interrupt_nest;

extern int __rt_ffs(int value);

/**

* 调度器锁的层数

*/

static rt_int16_t rt_scheduler_lock_nest;

/**

* 线程优先级链表数组: 是一个含有RT_THREAD_PRIORITY_MAX

* 个数组元素的链表

*/

rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];

/**

* 指向当前正在运行的线程

*/

struct rt_thread *rt_current_thread;

/**

* 当前的优先级

*/

rt_uint8_t rt_current_priority;

/** 最大支持256个优先级: 任务的个数没限制 */

#if RT_THREAD_PRIORITY_MAX > 32

rt_uint32_t rt_thread_ready_priority_group;

rt_uint8_t rt_thread_ready_table[32];

#else

/** 最大支持32个优先级 */

rt_uint32_t rt_thread_ready_priority_group;

#endif

/**

* 僵尸线程链表

*/

rt_list_t rt_thread_defunct;

#ifdef RT_USING_HOOK

static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread
*to);

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

** 函数名称: rt_scheduler_sethook

** 函数功能: 设置调度器的钩子函数

** 入口参数: hook 钩子函数指针

** 返 回 值: 无

** 调    用:

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

void rt_scheduler_sethook(void (*hook)(struct rt_thread *from, struct rt_thread *to))

{

rt_scheduler_hook = hook;

}

#ifdef RT_USING_OVERFLOW_CHECK

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

** 函数名称: _rt_scheduler_stack_check

** 函数功能: 调度器栈检查

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

** 返 回 值: 无

** 调    用: rt_schedule

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

static void _rt_scheduler_stack_check(struct rt_thread *thread)

{

/** 参数检查 */

RT_ASSERT(thread != RT_NULL);

if ((rt_uint32_t)thread->sp <= (rt_uint32_t)thread->stack_addr || (rt_uint32_t)thread->sp >

(rt_uint32_t)thread->stack_addr + (rt_uint32_t)thread->stack_size) {

rt_uint32_t level;

rt_kprintf("thread:%s stack overflow\n", thread->name);

#ifdef RT_USING_FINSH

{

extern long list_thread(void);

list_thread();

}

#endif

level = rt_hw_interrupt_disable();

while (level);

} else if ((rt_uint32_t)thread->sp <= ((rt_uint32_t)thread->stack_addr + 32)) {

rt_kprintf("warning: %s stack is close to end of stack address.\n",

thread->name);

}

}

#endif

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

** 函数名称: rt_system_scheduler_init

** 函数功能: 系统调度器初始化

** 入口参数: 无

** 返 回 值: 无

** 调    用: rtthread_startup

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

void rt_system_scheduler_init(void)

{

register rt_base_t offset;

/** 调度器锁的层数初始化为0 */

rt_scheduler_lock_nest =
0;

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("start scheduler: max priority 0x%02x\n",

RT_THREAD_PRIORITY_MAX));

/** 初始化优先级链表数组 */

for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++) {

rt_list_init(&rt_thread_priority_table[offset]);

}

/** 系统当前优先级为RT_THREAD_PRIORITY_MAX-1 */

rt_current_priority = RT_THREAD_PRIORITY_MAX -
1;

/** 当前线程指针为RT_NULL */

rt_current_thread = RT_NULL;

/** 初始化就绪组 */

rt_thread_ready_priority_group =
0;

#if RT_THREAD_PRIORITY_MAX > 32

/** 初始化就绪表 */

rt_memset(rt_thread_ready_table,
0, sizeof(rt_thread_ready_table));

#endif

/** 初始化僵尸线程链表 */

rt_list_init(&rt_thread_defunct);

}

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

** 函数名称: rt_system_scheduler_init

** 函数功能: 系统调度器初始化

** 入口参数: 无

** 返 回 值: 无

** 调    用: rtthread_startup

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

void rt_system_scheduler_init(void)

{

register rt_base_t offset;

/** 调度器锁的层数初始化为0 */

rt_scheduler_lock_nest =
0;

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("start scheduler: max priority 0x%02x\n",

RT_THREAD_PRIORITY_MAX));

/** 初始化优先级链表数组 */

for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++) {

rt_list_init(&rt_thread_priority_table[offset]);

}

/** 系统当前优先级为RT_THREAD_PRIORITY_MAX-1 */

rt_current_priority = RT_THREAD_PRIORITY_MAX -
1;

/** 当前线程指针为RT_NULL */

rt_current_thread = RT_NULL;

/** 初始化就绪组 */

rt_thread_ready_priority_group =
0;

#if RT_THREAD_PRIORITY_MAX > 32

/** 初始化就绪表 */

rt_memset(rt_thread_ready_table,
0, sizeof(rt_thread_ready_table));

#endif

/** 初始化僵尸线程链表 */

rt_list_init(&rt_thread_defunct);

}

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

** 函数名称: rt_schedule

** 函数功能: 执行一次线程调度

** 入口参数: 无

** 返 回 值: 无

** 调    用:

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

void rt_schedule(void)

{

rt_base_t level;

struct rt_thread *to_thread;

struct rt_thread *from_thread;

/** 禁止全局中断 */

level = rt_hw_interrupt_disable();

/** 检查调度器是否上锁,如果没有上锁执行调度

* 如果被上锁,直接退出

*/

if (rt_scheduler_lock_nest ==
0) {

register rt_ubase_t highest_ready_priority;

/** 计算出系统线程中的最高优先级 */

#if RT_THREAD_PRIORITY_MAX <= 32

highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group)
- 1;

#else

register rt_ubase_t number;

number = __rt_ffs(rt_thread_ready_priority_group) - 1;

highest_ready_priority = (number << 3) +
__rt_ffs(rt_thread_ready_table[number]) - 1;

#endif

/** 由优先级找到对应的线程句柄 */

to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,

struct rt_thread,

tlist);

/** 如果最高优先级线程非当前线程,切换到新线程去执行 */

if (to_thread != rt_current_thread)
{

rt_current_priority =
(rt_uint8_t)highest_ready_priority;

from_thread         = rt_current_thread;

rt_current_thread   =
to_thread;

RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread));

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,

("[%d]switch to priority#%d "

"thread:%.*s(sp:0x%p), "

"from thread:%.*s(sp: 0x%p)\n",

rt_interrupt_nest, highest_ready_priority,

RT_NAME_MAX, to_thread->name, to_thread->sp,

RT_NAME_MAX, from_thread->name, from_thread->sp));

#ifdef RT_USING_OVERFLOW_CHECK

_rt_scheduler_stack_check(to_thread);

#endif

/** 如果中断嵌套的层数为0,为正常的上下文切换 */

if (rt_interrupt_nest ==
0) {

rt_hw_context_switch((rt_uint32_t)&from_thread->sp,

(rt_uint32_t)&to_thread->sp);

} else {

/** 如果中断嵌套的层数不为0,说明是在中断处理中进行的任务切换

* 调用中断上下文切换函数

*/

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n"));

rt_hw_context_switch_interrupt((rt_uint32_t)&from_thread->sp,

(rt_uint32_t)&to_thread->sp);

}

}

}

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

}

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

** 函数名称: rt_schedule_insert_thread

** 函数功能: 将线程插入到就绪队列中

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

** 返 回 值: 无

** 调    用:

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

void rt_schedule_insert_thread(struct rt_thread* thread)

{

register rt_base_t temp;

/** 参数检查 */

RT_ASSERT(thread != RT_NULL);

/** 禁止全局中断 */

temp = rt_hw_interrupt_disable();

/** 设置线程的状态为就绪态 */

thread->stat = RT_THREAD_READY;

/** 将线程插入到优先级队列中 */

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

&(thread->tlist));

#if
RT_THREAD_PRIORITY_MAX <= 32

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("insert thread[%.*s], the priority: %d\n",

RT_NAME_MAX, thread->name, thread->current_priority));

#else

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,

("insert thread[%.*s], the priority: %d 0x%x %d\n",

RT_NAME_MAX,

thread->name,

thread->number,

thread->number_mask,

thread->high_mask));

#endif

/** 设置就绪表和就绪组 */

#if
RT_THREAD_PRIORITY_MAX > 32

rt_thread_ready_table[thread->number]
|= thread->high_mask;

#endif

rt_thread_ready_priority_group |=
thread->number_mask;

/** 使能全局中断 */

rt_hw_interrupt_enable(temp);

}

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

** 函数名称: rt_schedule_remove_thread

** 函数功能: 将线程从就绪队列中移除

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

** 返 回 值: 无

** 调    用:

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

void rt_schedule_remove_thread(struct rt_thread* thread)

{

register rt_base_t temp;

RT_ASSERT(thread != RT_NULL);

/** 禁止全局中断 */

temp = rt_hw_interrupt_disable();

#if RT_THREAD_PRIORITY_MAX <= 32

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
("remove thread[%.*s], the priority: %d\n",

RT_NAME_MAX, thread->name,

thread->current_priority));

#else

RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,

("remove thread[%.*s], the priority: %d 0x%x %d\n",

RT_NAME_MAX,

thread->name,

thread->number,

thread->number_mask,

thread->high_mask));

#endif

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

rt_list_remove(&(thread->tlist));

if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority])))
{

#if RT_THREAD_PRIORITY_MAX > 32

rt_thread_ready_table[thread->number]
&= ~thread->high_mask;

if (rt_thread_ready_table[thread->number]
== 0) {

rt_thread_ready_priority_group &=
~thread->number_mask;

}

#else

rt_thread_ready_priority_group &=
~thread->number_mask;

#endif

}

/** 使能全局中断 */

rt_hw_interrupt_enable(temp);

}

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

** 函数名称: rt_enter_critical

** 函数功能: 进入临界区

** 入口参数: 无

** 返 回 值: 无

** 调    用:

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

void rt_enter_critical(void)

{

register rt_base_t level;

/** 禁止全局中断 */

level = rt_hw_interrupt_disable();

/** 调度器锁的层数加1 */

rt_scheduler_lock_nest++;

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

}

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

** 函数名称: rt_exit_critical

** 函数功能: 退出临界区

** 入口参数: 无

** 返 回 值: 无

** 调    用:

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

void rt_exit_critical(void)

{

register rt_base_t level;

/** 禁止全局中断 */

level = rt_hw_interrupt_disable();

/** 调度器锁层数减1 */

rt_scheduler_lock_nest--;

/** 当调度器锁的值小于等于0时会触发调度 */

if (rt_scheduler_lock_nest <=
0) {

rt_scheduler_lock_nest =
0;

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

/** 调度 */

rt_schedule();

} else {

/** 使能全局中断 */

rt_hw_interrupt_enable(level);

}

}

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

** 函数名称: rt_critical_level

** 函数功能: 获取调度器锁层数

** 入口参数: 无

** 返 回 值: 调度器锁的层数

** 调    用:

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

rt_uint16_t rt_critical_level(void)

{

return rt_scheduler_lock_nest;

}

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

时间: 2024-08-27 12:41:22

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

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

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

java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提

这里举个例子讲解,同步synchronized在什么地方加,以及同步的前提: * 1.必须要有两个以上的线程,才需要同步. * 2.必须是多个线程使用同一个锁. * 3.必须保证同步中只能有一个线程在运行,锁加在哪一块代码 那么我们要思考的地方有:1.知道我们写的哪些是多线程代码 2.明确共享数据 3.明确多线程运行的代码中哪些语句是操作共享数据的.. 4.要确保使用同一个锁. 下面的代码:需求:两个存户分别往银行存钱,每次村100块,分三次存完. class bank{ private int

Linux内核分析(五)----字符设备驱动实现

原文:Linux内核分析(五)----字符设备驱动实现 Linux内核分析(五) 昨天我们对linux内核的子系统进行简单的认识,今天我们正式进入驱动的开发,我们今后的学习为了避免大家没有硬件的缺陷,我们都会以虚拟的设备为例进行学习,所以大家不必害怕没有硬件的问题. 今天我们会分析到以下内容: 1.      字符设备驱动基础 2.      简单字符设备驱动实现 3.      驱动测试 l  字符设备基础 1.       字符设备描述结构 在linux2.6内核中,使用cdev结构体描述一

Linux内核设计基础(五)之内存管理

我感觉学习操作系统首先要从内存分配和管理入手.首先我们应该知道现代操作系统是以页为单位进行内存管理的,32位体系结构支持4KB的页,而64位体系结构支持8KB的页.页是用来分配的,如何才能进行高效和充分的利用,这是内存管理单元(MMU)应当仔细考虑的. 页分配 内核用结构体struct page表示每个物理页.内核用这一结构来管理系统中所有的页,因为内核需要知道一个页是否空闲(也就是页有没有被分配),如果页已经被分配,内核需要知道谁拥有这个页,拥有者可能是用户空间进程.动态分配的内核数据.静态内

把握linux内核设计(五):下半部机制之工作队列及几种机制的选择

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 工作队列是下半部的另外一种将工作推后执行形式.和软中断.tasklet不同,工作队列将工作推后交由一个内核线程去执行,并且该下半部总会在进程上下文中执行.这样,工作队列允许重新调度甚至是睡眠. 所以,如果推后执行的任务需要睡眠,就选择工作队列.如果不需要睡眠,那就选择软中断或tasklet.工作队列是唯一能在进程上下文中运行的下半部实现机制,也只有它才可以睡眠. 工作队列子系

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

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

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

一.前言 RT-Thread中提供的线程调度器是基于全抢占式优先级的调度,在系统中除了中断处理函数.调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自身.系统总共支持256个优先级(0 - 255,数值越小的优先级越高,0为最高优先级,255分配给空闲线程使用,一般用户不使用.在一些资源比较紧张的系统中,可以根据情况选择只支持8个或32个优先级的系统配置).在系统中,当有比当前线程优先级还要高的线程就绪时,当前线程将立刻被换出,高优先级线程抢占处

RT-thread内核之线程调度器

http://www.cnblogs.com/King-Gentleman/p/4278012.html 一.前言 RT-Thread中提供的线程调度器是基于全抢占式优先级的调度,在系统中除了中断处理函数.调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自身.系统总共支持256个优先级(0 - 255,数值越小的优先级越高,0为最高优先级,255分配给空闲线程使用,一般用户不使用.在一些资源比较紧张的系统中,可以根据情况选择只支持8个或32个优先

十天学Linux内核之第五天---有关Linux文件系统实现的问题

有时间睡懒觉了,却还是五点多醒了,不过一直躺倒九点多才算起来,昨晚一直在弄飞凌的嵌入式开发板,有些问题没解决,自己电脑系统的问题,虽然Win10发布了,,但我还是好喜欢XP呀,好想回家用用家里的XP来玩玩这块板子,不知不觉也第五天了,感觉代码都有些模糊,连自己都不是很清楚了,担心现在分享起来比较困惑,各路大神多加批评呀,觉得渣渣的尽量指正出来,拉出来批评,今天还是来总结一下有关Linux文件系统的问题吧~ Linux的使用和用户空间程序的编程和文件系统有着密切的关系,文件系统的概念大家应该都有些