mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 13:13:08 +08:00
sched/signal: fix the occasional issue where SIGCONT was not executed
Build Documentation / build-html (push) Has been cancelled
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:
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user