Repository navigation
Conversation
cc15710 to
7c4b539
Compare
|
这个 PR 挂在 1. 补丁的目标文件已经不存在了本 PR 改的是
所以本 PR 现在无法直接应用。对应关系大致是:
2. 核心判别式与 PR #11907 完全一致本 PR 的关键判断是:
我最近提的 PR #11907 独立得出了同一个判别式( 3. 一处值得决策的差异:YIELD 在哪里清除
两者的分支结果等价,差别在于 YIELD 生命周期的语义。这里有个实测现象可以参照:当前代码在切走线程时就清 YIELD,所以一个线程 4. 我可以帮忙验证我本地已有可用的测试环境(QEMU vexpress-a9 + xpack arm-none-eabi-gcc 15.2.1,以及一组同优先级线程的顺序/轮转测试:信号量唤醒顺序、启动顺序、tick 轮转公平性),已经把 #11907 的修复前/后都跑过。 如果需要,我可以把这个补丁按当前文件结构 port 一份,在 QEMU 上跑同样的用例给出对照数据(单核 + SMP 都可以)。作者当年提到"SMP 正在研究怎么测试",这部分我可以补。 要我先做 port + 测试吗?还是维护者认为 #11907 已经覆盖了同等语义、本 PR 可以直接关闭,也请明示——这样至少不让它继续无声挂着。 |
|
按上一条评论里说的,我把这个补丁 port 到当前文件结构并跑了单核测试。顺序问题确实修好了,但引入了一个可复现的重复释放。 Port 方式只改了
结果(QEMU vexpress-a9,UP)
顺序和轮转都对,说明判别式本身是对的。但跑 utest 时稳定触发: addr2line 还原: 也就是 idle 线程在回收已结束线程时,对同一个 TCB 做了第二次释放。连续两次运行都在同一位置复现(每次都是 utest 跑到 隔离实验:不是 YIELD 清除位置的问题我做了个对照:保留 insert 侧的改动,但把 所以问题不在"YIELD 清除从 rt_schedule 搬到 insert 末尾"这一半,而在 insert 侧延后写 READY这一半:插入期间线程的 作为对照,PR #11907 用的是同一个判别式,但保留"先写 READY、再判断",判别式改用进入函数时保存的 我没有做完的部分
建议判别式( 如果这个方向维护者认可,建议以 #11907 为基础推进,本 PR 可以关闭;如果认为 #6645 的写法更合适,需要先查清上面那个重复释放。 |
|
补上 SMP 数据(上一条里我说"SMP 没测",现在测了)。同时更正一条我自己的误判。 SMP 结果(QEMU vexpress-a9,
|
| 项目 | 本补丁 port | PR #11907 |
|---|---|---|
| 信号量唤醒顺序 | AB ✅ |
AB ✅ |
| 启动顺序 | CD ✅ |
CD ✅ |
| 时间片轮转(3 线程轮转,切片 5 tick) | 34/33/32%,1.07x,OK | 35/33/31%,1.10x,OK |
| 调度组 utest | passed | passed |
SMP 下两边都能修好顺序,轮转也没问题。
更正:那条 rt_thread_delete 断言是我的测试台问题
SMP 跑完后我的临时轮转脚本清理时打印了:
(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread) assertion failed
at function:rt_thread_delete, line number:614
我一开始怀疑是 TCB 被破坏,于是在同样的 SMP 配置下又跑了 PR #11907——完全相同位置同样报错。所以这是我那段临时脚本的缺陷(SMP 下直接 rt_thread_delete 仍在其他核上运行的线程),与这两个补丁都无关。它在测量之后才触发,不影响上表的顺序/轮转数据。
UP 与 SMP 的差异值得注意
- SMP:本补丁 port 跑调度组 utest 通过,没有出现内存断言。
- UP:稳定出现
(small_mem != RT_NULL)断言,backtrace 是rt_free ← rt_defunct_execute ← idle_thread_entry,即 idle 回收已结束线程时二次释放;两次运行都在同一点复现。
也就是说这个重复释放目前只在单核路径观察到,跟着 scheduler_up.c 里"延后写 READY"的实现走;多核路径没复现出来(可能只是没触发到,不代表没问题)。
综合结论
- 判别式
(stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING是对的——UP/SMP 都验证了它能把顺序修正过来,两个实现都做到了。 - 分歧在实现手段:延后写 READY(本补丁)在单核路径引出了重复释放;保存
stat_before局部量([kernel][scheduler] fix: keep FIFO order for same-priority threads #11907)没有。隔离实验确认这与 YIELD 清除位置无关,问题出在插入期间线程状态与实际不一致。 - 我仍然没有定位到那个重复释放的根因,只能说它跟随该设计选择出现。
如果维护者希望以 #6645 为基础,需要先查清 UP 下这个二次释放;若以 #11907 为基础,判别式一致,且目前 UP/SMP 都没有出现内存问题。
[
最近再次研究了之前提交的PR #6232 ,发现存在不少问题和新的bug, 打个patch, 同时提供一下utest
具体信息,参考 时间片调度算法issue解决后续及utest测试
已在stm32f407disc1测试, SMP 正在研究怎么测试。
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up