sched/signal: fix the occasional issue where SIGCONT was not executed
Build Documentation / build-html (push) Has been cancelled

In multi-core scenarios, a problem occurs: the target thread receives SIGCONT but does not execute them.

Further analysis reveals that in the sig_dispatch function, the target thread is placed in the readytorun queue only if the SIGCONT signal is sent and the target thread is in the TSTATE_TASK_STOPPED state. However, if the following conditions occur:

CPU0				CPU1
dispatch SIGSTOP
dispatch SIGCONT(check state)
				sched_suspend(set task_state = TSTATE_TASK_STOPPED)

This causes the target thread on CPU 1 to receive SIGCONT but not be placed in the readytorun queue, remaining in the stopped state.
Therefore, A flag is needed to indicate whether the SIGCONT action has been executed. At the same time, the critical section protection range of nxsig_stop_task needs to be expanded to prevent another thread from executing the SIGCONT logic during the execution of this function.

Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
This commit is contained in:
wangzhi16
2025-10-20 21:58:29 +08:00
committed by Xiang Xiao
parent d11307b236
commit a73ff585f1
+14
View File
@@ -36,6 +36,7 @@
#include "sched/sched.h"
#include "sched/queue.h"
#include "signal/signal.h"
#ifdef CONFIG_SMP
/****************************************************************************
@@ -102,11 +103,24 @@ void nxsched_suspend(FAR struct tcb_s *tcb)
{
irqstate_t flags;
bool switch_needed;
FAR sq_entry_t *entry;
DEBUGASSERT(tcb != NULL);
flags = enter_critical_section();
/* Check if received SIGCONT */
sq_for_every(&tcb->sigpendactionq, entry)
{
FAR sigq_t *sigq = (FAR sigq_t *)entry;
if (sigq->info.si_signo == SIGCONT)
{
leave_critical_section(flags);
return;
}
}
/* Check the current state of the task */
if (tcb->task_state >= FIRST_BLOCKED_STATE &&