ARMv7-A SMP: Add a little logic to signal handling.
This commit is contained in:
parent
eb9f8074c0
commit
f77dcdf323
@ -153,6 +153,18 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)up_sigdeliver;
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* In an SMP configuration, the interrupt disable logic also
|
||||
* involves spinlocks that are configured per the TCB irqcount
|
||||
* field. This is logically equivalent to enter_critical_section().
|
||||
* The matching call to leave_critical_section() will be
|
||||
* performed in up_sigdeliver().
|
||||
*/
|
||||
|
||||
DEBUGASSERT(tcb->irqcount < INT16_MAX);
|
||||
tcb->irqcount++;
|
||||
#endif
|
||||
|
||||
/* And make sure that the saved context in the TCB is the same
|
||||
* as the interrupt return context.
|
||||
*/
|
||||
@ -183,6 +195,19 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* In an SMP configuration, the interrupt disable logic also
|
||||
* involves spinlocks that are configured per the TCB irqcount
|
||||
* field. This is logically equivalent to enter_critical_section();
|
||||
* The matching leave_critical_section will be performed in
|
||||
* The matching call to leave_critical_section() will be performed
|
||||
* in up_sigdeliver().
|
||||
*/
|
||||
|
||||
DEBUGASSERT(tcb->irqcount < INT16_MAX);
|
||||
tcb->irqcount++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_sigdeliver.c
|
||||
*
|
||||
* Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -103,18 +103,24 @@ void up_sigdeliver(void)
|
||||
|
||||
/* Then restore the task interrupt state */
|
||||
|
||||
up_irq_restore(regs[REG_CPSR]);
|
||||
leave_critical_section(regs[REG_CPSR]);
|
||||
|
||||
/* Deliver the signals */
|
||||
/* Deliver the signal */
|
||||
|
||||
sigdeliver(rtcb);
|
||||
|
||||
/* Output any debug messages BEFORE restoring errno (because they may
|
||||
* alter errno), then disable interrupts again and restore the original
|
||||
* errno that is needed by the user logic (it is probably EINTR).
|
||||
*
|
||||
* REVISIT: In SMP mode up_irq_save() probably only disables interrupts
|
||||
* on the local CPU. We do not want to call enter_critical_section()
|
||||
* here, however, because we don't want this state to stick after the
|
||||
* call to up_fullcontextrestore().
|
||||
*/
|
||||
|
||||
sinfo("Resuming\n");
|
||||
|
||||
(void)up_irq_save();
|
||||
rtcb->pterrno = saved_errno;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user