Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
SMP
关于SMP里是怎么调度的
发布于 2023-05-02 01:25:10 浏览:792
订阅该版
[tocm] # 1.做一个简单测试 在**qemu-vexpress-a9**的bsp下开启SMP功能,设置为两个核心 ![Untitled.png](https://oss-club.rt-thread.org/uploads/20230502/8fcc707c6c595fe4ab48d0d3b480c0c8.png.webp) 在main里创建两个线程,分别绑定cpu0和cpu1 ```c tid1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 11, 5); rt_thread_control(tid1, RT_THREAD_CTRL_BIND_CPU, (void *)0); tid2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 11, 5); rt_thread_control(tid2, RT_THREAD_CTRL_BIND_CPU, (void *)1); if (tid1 != RT_NULL) rt_thread_startup(tid1); if (tid2 != RT_NULL) rt_thread_startup(tid2); ``` 在这两个线程里面通过判断标志位,进行死循环耗死cpu或者延时1ms让出cpu ```c static void thread1_entry(void *parameter) { for (;;) { if (thread1_sta == 1); else rt_thread_mdelay(1); } } static void thread2_entry(void *parameter) { for (;;) { if (thread2_sta == 1); else rt_thread_mdelay(1); } } ``` 编写msh命令,通过msh来改变该标志位 ```c static int change_thread_state(int argc, char *argv[]) { if (argc == 3) { if(atoi(argv[1]) == 1) { thread1_sta = (uint8_t)atoi(argv[2]); } else if(atoi(argv[1]) == 2) { thread2_sta = (uint8_t)atoi(argv[2]); } } else { rt_kprintf("[Usage]:change_thread_state [threadx] [state]\r\n"); } return RT_EOK; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(change_thread_state, change thread state); ``` 编译运行qemu,ps一下可以看到tshell运行在cpu0上 ![Untitled 1.png](https://oss-club.rt-thread.org/uploads/20230502/523f3d3a32831155f711df3b306a58cb.png.webp) 此时我们修改thread1的标志位,让其把cpu0的资源耗尽,再次ps可以看到tshell已经转移到cpu1上运行了,因为tshell线程没有绑定核心,所以在smp系统里面是可以被调度到其他核心上运行的 ![Untitled 2.png](https://oss-club.rt-thread.org/uploads/20230502/4ed3d79dacd449eb30a6c5bf0c405ca4.png.webp) 如果此时我们在释放掉cpu0的资源,tshell又会再次被调到回cpu0上 ![Untitled 3.png](https://oss-club.rt-thread.org/uploads/20230502/4509e9f47bf2e1160848bd4ac89123d3.png.webp) 这个简单的测试让我好奇在smp系统里面rt_schedule是怎么决策一个线程运行在哪个核心上的 # 2.查找资料 查阅官方文档的smp章节并没有找到相关内容,一时间没有什么头绪,询问了一下万能的gpt提到与CPU亲和性和多级反馈队列(MLFQ)有关,CPU亲和度通过设置CPU掩码来实现,bindcpu的操作就是通过设置cpumask实现,但我看到**rt_thread_cpu_bind**函数里面是对**thread->bind_cpu**进行操作,感觉他的回答不靠谱,试着问了一下它MLFQ的代码在哪 ![Untitled 4.png](https://oss-club.rt-thread.org/uploads/20230502/5f6f9b1b18b33efb10c982f5b26b5108.png.webp) 那好吧,还是只能自己慢慢翻源码学吧 # 3.尝试阅读源码 在cortex-m系列的mcu里面,通过systick给系统时基,通过寻找相关代码,可以看到在smp里面每个核心都会有自己的时基(其实挺好奇两个中断服务程序是不是分别运行在两个核心上的,不过没有查到相关资料) ![Untitled 5.png](https://oss-club.rt-thread.org/uploads/20230502/babc7186db7d5ddfeb60161a2258bef4.png.webp) ![Untitled 6.png](https://oss-club.rt-thread.org/uploads/20230502/f03f8f31a474849cb710c65bab9be9db.png.webp) ![Untitled 7.png](https://oss-club.rt-thread.org/uploads/20230502/a480424474a7798bfa0b2a6bb73dbfb7.png.webp) 可以看到rt_tick_get等一些函数用到的rt_tick是以cpu0为准,试着把time2_isr里面的**rt_tick_increase**函数注释掉,整个系统依然能够运行,但是会导致cpu1上的时间片不生效。 ![Untitled 8.png](https://oss-club.rt-thread.org/uploads/20230502/1386de5873a02ad8e7baddbf3ba29a80.png.webp) **rt_tick_increase**里面会触发**rt_schedule**,再看看rt_schedule里发现比stm32里面的多了一个pcpu,以及原本的**from_thread**变成**current_thread**了,这个**current_thread**会指向当前核心运行的线程。 ![Untitled 9.png](https://oss-club.rt-thread.org/uploads/20230502/d726ee73fcb48e277c80f5fdd5878b50.png.webp) 当就绪线程的优先级分组或者CPU 核心的优先级分组不为空时,选出最高优先级的线程,加到就绪链表当中 ![Untitled 10.png](https://oss-club.rt-thread.org/uploads/20230502/23ee2269aeeeba41a9b6f31e588017c2.png.webp) **rt_schedule_insert_thread**里会判断这个线程绑定的核心是不是当前核心,增加到不同核心的就绪链表当中 ![Untitled 11.png](https://oss-club.rt-thread.org/uploads/20230502/4ff2c620b693355b887e86e2331d84ff.png.webp) ![Untitled 12.png](https://oss-club.rt-thread.org/uploads/20230502/d9d8c8787fa22bb88e1627a3a1409a14.png.webp) 随后触发IPI核间中断 ![Untitled 13.png](https://oss-club.rt-thread.org/uploads/20230502/20d14fedaafbad416ac03ea4d10fa181.png) ![Untitled 14.png](https://oss-club.rt-thread.org/uploads/20230502/9c740f8049b69fb349d88eb2330c81ab.png.webp) ipi中断处理函数里面会再次调用**rt_schedule**(已经开始看不懂了T_T) ![Untitled 15.png](https://oss-club.rt-thread.org/uploads/20230502/b380d47ca15bcfa81dfeb2fc20e82d25.png.webp) 回到刚刚还没结束的**rt_schedule**,选出最高优先级的线程后,设置**to_thread**的**oncpu**为当前运行的cpu,如果目标线程与当前线程不同,会把当前cpu的现在的优先级改为最高的优先级并且会把目标线程从调度器里面删除(没能理解),修改目标线程状态,最后切换上下文环境。 ![Untitled 16.png](https://oss-club.rt-thread.org/uploads/20230502/d8d37a839930405318a4b0fe7ce39af7.png.webp) 切换上下文的函数会比stm32上的多了第三个个参数,因为对汇编不熟悉,看不懂,只能猜测是与目标线程的cpu核心有关。 ```c rt_hw_context_switch((rt_ubase_t)¤t_thread->sp, (rt_ubase_t)&to_thread->sp, to_thread); ``` 感觉对比cortex-m的调度器变化还是比较大的,看到部分源码和汇编代码感到无从下手,分析的内容可能也有不少问题,而且还没开始分析在中断环境下的切换情况,在cortex-m的代码里**rt_hw_context_switch**和**rt_hw_context_switch_interrupt**是会跳转到同一个汇编函数的,在cortex-a里面两者被分开了,估计也有不少的区别。对于IPI核间中断也没有什么理解,除了在多核启动阶段会通过**rt_hw_secondary_cpu_up**触发一次拉起其他核心,在**rt_schedule**里还会通过**rt_schedule_insert_thread**触发,看到我比较懵逼,也不知道该去哪查了,希望大佬们能指导下。
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
792
关于作者
NinaGon
这家伙很懒,什么也没写!
提问
2
回答
1
被采纳
0
关注TA
发私信
相关问题
1
aarch64有计划支持SMP吗
2
SMP重新定义中断处理函数的问题
3
rt_tick_increase()在SMP时只增加当前核的TICK?
4
RISCV smp系统调度异常问题请教
5
qemu-vexpress-a9 在SMP情况下GDB无法调试
6
为什么在k210上使用多核smp总是会卡死
7
RT-Thread SMP核弹碰撞树莓派
8
请教多核SMP功能验证
9
明年开始玩SMP多核处理器
10
建议RT-Thread支持SMP
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
在RT-Thread Studio中构建前执行python命令
2
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
3
CherryUSB开发笔记(一):FSDEV USB IP核的 HID Remote WakeUp (USB HID 远程唤醒) 2025-01-18 V1.1
4
RT-thread 缩写字典
5
RT Thread 源码分析笔记 :线程和调度器
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
Bootloader
AT
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
用户名由3_15位
7
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
xusiwei1236
3
个答案
1
次被采纳
踩姑娘的小蘑菇
1
个答案
1
次被采纳
张世争
1
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
14
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
2
次点赞
Ghost_Girls
1
篇文章
6
次点赞
xiaorui
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部