mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 21:36:28 +08:00
arch: fix the issue of asynchronous signal processing
in SMP, signal processing cannot be nested, we use xcp.sigdeliver to identify whether there is currently a signal being processed, but this state does not match the actual situation One possible scenario is that signal processing has already been completed, but an interrupt occurs, resulting in xcp.sigdeliver not being correctly set to NULL, At this point, a new signal arrives, which can only be placed in the queue and cannot be processed immediately Our solution is that signal processing and signal complete status are set in the same critical section, which can ensure status synchronization Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
@@ -84,14 +84,15 @@ void sparc_sigdeliver(void)
|
||||
|
||||
sparc_copystate(regs, rtcb->xcp.regs);
|
||||
|
||||
retry:
|
||||
#ifdef CONFIG_SMP
|
||||
/* In the SMP case, up_schedule_sigaction(0) will have incremented
|
||||
* 'irqcount' in order to force us into a critical section. Save the
|
||||
* pre-incremented irqcount.
|
||||
*/
|
||||
|
||||
saved_irqcount = rtcb->irqcount - 1;
|
||||
DEBUGASSERT(saved_irqcount >= 0);
|
||||
saved_irqcount = rtcb->irqcount;
|
||||
DEBUGASSERT(saved_irqcount >= 1);
|
||||
|
||||
/* Now we need call leave_critical_section() repeatedly to get the irqcount
|
||||
* to zero, freeing all global spinlocks that enforce the critical section.
|
||||
@@ -144,6 +145,12 @@ void sparc_sigdeliver(void)
|
||||
|
||||
set_errno(saved_errno);
|
||||
|
||||
if (!sq_empty(&rtcb->sigpendactionq) &&
|
||||
(rtcb->flags & TCB_FLAG_SIGNAL_ACTION) == 0)
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Modify the saved return state with the actual saved values in the
|
||||
* TCB. This depends on the fact that nested signal handling is
|
||||
* not supported. Therefore, these values will persist throughout the
|
||||
@@ -195,5 +202,8 @@ void sparc_sigdeliver(void)
|
||||
*/
|
||||
|
||||
board_autoled_off(LED_SIGNAL);
|
||||
#ifdef CONFIG_SMP
|
||||
rtcb->irqcount--;
|
||||
#endif
|
||||
sparc_fullcontextrestore(regs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user