Skip to content

[kernel/signal] fix: respect thread suspend mode during signal delivery - #11723

Open
liulangrenaaa wants to merge 1 commit into
RT-Thread:masterfrom
liulangrenaaa:new_bug4-signal
Open

[kernel/signal] fix: respect thread suspend mode during signal delivery#11723
liulangrenaaa wants to merge 1 commit into
RT-Thread:masterfrom
liulangrenaaa:new_bug4-signal

Conversation

@liulangrenaaa

@liulangrenaaa liulangrenaaa commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

拉取/合并请求描述:(PR description)

为什么提交这份PR (why to submit this PR)

当前 RT-Thread native signal delivery 会无条件唤醒所有处于 suspended 状态的线程,而不会考虑线程当前的 suspend mode。

这会破坏线程阻塞等待的语义。

例如,当线程通过 rt_sem_take() 在不可中断等待 (RT_UNINTERRUPTIBLE) 中等待信号量时,如果此时收到普通信号:

  • 线程可能会被错误地从信号量等待队列中移除;
  • rt_sem_take() 返回 -RT_EINTR
  • 但线程实际上并没有成功获取信号量。

类似问题不仅限于 semaphore,也可能影响其他依赖 thread suspend/wakeup 机制的同步原语,例如 mutex、event、mailbox 和 message queue。

根本原因是 signal delivery 路径没有遵守 RT-Thread thread suspend semantics,导致 signal wakeup 错误地抢占了其他 wakeup source(例如 IPC release 或 timeout)的 ownership。


你的解决方案是什么 (what is your solution)

在唤醒 suspended thread 之前,同时检查 pending signal 和完整 suspend state,并在 scheduler ownership 下决定该 signal 是否允许唤醒线程。

当前 signal wakeup 规则:

  • RT_THREAD_STAT_SIGNAL_WAIT

    • 保留 rt_signal_wait() 的正常 signal wakeup 行为。
  • RT_INTERRUPTIBLE

    • 普通信号可以唤醒等待线程。
  • RT_KILLABLE

    • 根据 RT-Thread native signal semantics,仅 SIGKILLSIGSTOP 可以唤醒等待线程。
  • RT_UNINTERRUPTIBLE

    • 普通信号不会中断等待,signal 保持 pending,并在正常等待完成后继续处理。

同时:

  • 在尝试 signal wakeup 前设置 RT_EINTR
  • 在调用 rt_thread_resume() / rt_thread_wakeup() 前释放 signal lock;
  • 避免 signal delivery 覆盖其他 wakeup source(例如 semaphore release 或 timeout)已经产生的成功结果。

另外修复:

  • rt_signal_wait() 收到 non-matching signal 时继续保持等待;
  • 保留 timed wait 剩余 timeout;
  • 避免 rt_signal_wait() 持有 pending signal 时错误设置 generic signal state;
  • 统一 signal mask 定义,避免 scheduler、native signal 和 testcase 使用不同实现。

测试覆盖 (Regression tests)

新增回归测试覆盖 native signal delivery 与不同 suspend mode 的交互:

  • signal_wait
  • non-matching signal wait
  • masked signal wait
  • NULL siginfo handling
  • pending signal deferred delivery
  • RT_UNINTERRUPTIBLE semaphore wait
  • RT_INTERRUPTIBLE semaphore wait
  • RT_KILLABLE semaphore wait
  • timeout handling
  • SIGSTOP handling according to RT-Thread native signal semantics

父分支测试失败:

  • RT_UNINTERRUPTIBLE wait 在收到普通信号后提前返回;
  • RT_KILLABLE wait 错误响应普通信号;
  • rt_signal_wait() 收到 non-matching signal 后提前结束等待。

修复后验证通过:

  • UP QEMU:

    • core.signal passed
  • Dual-core SMP QEMU:

    • core.signal passed
  • Build:

    • scons -C bsp/qemu-vexpress-a9 -j$(nproc) passed

请提供验证的bsp和config (provide the config and bsp)

  • BSP:

    • bsp/qemu-vexpress-a9
  • .config:

    • Default QEMU configuration
    • Enable native signal support
    • Enable utest and signal regression tests
  • Validation:

    • Parent revision with regression tests:

      • core.signal failed due to incorrect early wakeup and non-matching signal handling.
    • Fixed revision:

      • UP QEMU: passed
      • Dual-core SMP QEMU: passed
    • Build:

      • scons -C bsp/qemu-vexpress-a9 -j$(nproc) passed
  • action:

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 代码是高质量的 Code in this PR is of high quality
  • 已经使用clang-format 源码格式化工具确保格式符合RT-Thread代码规范 This PR has been formatted with clang-format and complies with RT-Thread code specification
  • 如果是新增bsp, 已经添加ci检查到.github/ALL_BSP_COMPILE.json 详细请参考链接BSP自查

@github-actions

Copy link
Copy Markdown

👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread!

为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。
To ensure your code complies with RT-Thread's coding style, please run the code formatting workflow by following the steps below (If the formatting of CI fails to run).


🛠 操作步骤 | Steps

  1. 前往 Actions 页面 | Go to the Actions page
    点击进入工作流 → | Click to open workflow →

  2. 点击 Run workflow | Click Run workflow

  • Use workflow from 保持默认分支(通常为 master
    Keep the default branch (usually master) in Use workflow from
  • branch 输入框填写 PR 分支 new_bug4-signal
    Enter PR branch new_bug4-signal in the branch field
  • 设置需排除的文件/目录(目录请以"/"结尾)
    Set files/directories to exclude (directories should end with "/")
  1. 等待工作流完成 | Wait for the workflow to complete
    格式化后的代码将作为独立提交推送至你的分支。
    The formatting changes will be pushed to your branch as a separate commit.

完成后,提交将自动更新至 new_bug4-signal 分支,关联的 Pull Request 也会同步更新。
Once completed, commits will be pushed to the new_bug4-signal branch automatically, and the related Pull Request will be updated.

如有问题欢迎联系我们,再次感谢您的贡献!💐
If you have any questions, feel free to reach out. Thanks again for your contribution!

@github-actions github-actions Bot added the Kernel PR has src relate code label Aug 20, 2026
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

📌 Code Review Assignment

🏷️ Tag: kernel

Reviewers: @GorrayLi @ReviewSun @hamburger-os @lianux-mm @wdfk-prog @xu18838022837

Changed Files (Click to expand)
  • src/scheduler_mp.c
  • src/signal.c
  • src/utest/signal_tc.c

📊 Current Review Status (Last Updated: 2026-08-20 17:31 CST)


📝 Review Instructions

  1. 维护者可以通过单击此处来刷新审查状态: 🔄 刷新状态
    Maintainers can refresh the review status by clicking here: 🔄 Refresh Status

  2. 确认审核通过后评论 LGTM/lgtm
    Comment LGTM/lgtm after confirming approval

  3. PR合并前需至少一位维护者确认
    PR must be confirmed by at least one maintainer before merging

ℹ️ 刷新CI状态操作需要具备仓库写入权限。
ℹ️ Refresh CI status operation requires repository Write permission.

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

@liulangrenaaa
liulangrenaaa marked this pull request as draft August 20, 2026 08:17
Native signal delivery resumed every suspended thread, including
RT_UNINTERRUPTIBLE IPC waiters. This could remove a waiter from a
semaphore, mutex, event, mailbox, or message queue wait list without
granting the corresponding resource, causing -RT_EINTR or inconsistent
higher-level state.

Inspect pending signals and suspend state under scheduler ownership.
Wake interruptible waiters for common signals, and wake killable waiters
only for SIGKILL and SIGSTOP according to RT-Thread suspend semantics.
Defer signals not allowed by the current wait mode. Release the signal
lock before waking the target thread. Also make scheduler-side
pending-signal preprocessing respect the suspend mode, preventing SMP
suspend-to-schedule races.

Keep rt_signal_wait() blocked for non-matching signals and preserve the
remaining timeout. Allow masked signals and NULL siginfo, handle suspend
failures without starting a timer, and preserve the outer interrupted
wait result when a signal handler invokes other kernel APIs.

Add regression coverage for RT-Thread native signal semantics,
including masked signals, non-matching signal waits, NULL siginfo,
and RT_KILLABLE SIGSTOP handling. The parent implementation fails the
regression test because uninterruptible and killable waits complete early
after SIGUSR1, and signal_wait returns early for a non-matching signal.

Validation:
- UP QEMU: core.signal passed.
- Dual-core SMP QEMU: core.signal passed.
- scons -C bsp/qemu-vexpress-a9 -j$(nproc) passed.

Signed-off-by: Hui Su <3164683437@qq.com>
@liulangrenaaa
liulangrenaaa marked this pull request as ready for review August 20, 2026 10:09
@liulangrenaaa liulangrenaaa changed the title [kernel/signal] fix: respect suspend state when delivering signals [kernel/signal] fix: respect thread suspend mode during signal delivery Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Kernel PR has src relate code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant