mirror of
https://github.com/apache/nuttx.git
synced 2026-05-29 20:56:47 +08:00
sched/signal: Optimize code logic
Adjust the up_schedule_sigaction function to facilitate subsequent spinlock optimization work. Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
This commit is contained in:
@@ -88,57 +88,30 @@ void up_schedule_sigaction(struct tcb_s *tcb)
|
||||
|
||||
if (tcb == this_task())
|
||||
{
|
||||
/* CASE 1: We are not in an interrupt handler and
|
||||
* a task is signalling itself for some reason.
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
if (!up_current_regs())
|
||||
{
|
||||
/* In this case just deliver the signal now. */
|
||||
tcb->xcp.saved_epc = up_current_regs()[REG_EPC];
|
||||
|
||||
(tcb->sigdeliver)(tcb);
|
||||
tcb->sigdeliver = NULL;
|
||||
}
|
||||
|
||||
/* CASE 2: We are in an interrupt handler AND the
|
||||
* interrupted task is the same as the one that
|
||||
* must receive the signal, then we will have to modify
|
||||
* the return state as well as the state in the TCB.
|
||||
*
|
||||
* Hmmm... there looks like a latent bug here: The following
|
||||
* logic would fail in the strange case where we are in an
|
||||
* interrupt handler, the thread is signalling itself, but
|
||||
* a context switch to another task has occurred so that
|
||||
* g_current_regs does not refer to the thread of this_task()!
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
up_current_regs()[REG_EPC] = (uint32_t)lm32_sigdeliver;
|
||||
up_current_regs()[REG_INT_CTX] = 0;
|
||||
|
||||
tcb->xcp.saved_epc = up_current_regs()[REG_EPC];
|
||||
/* And make sure that the saved context in the TCB
|
||||
* is the same as the interrupt return context.
|
||||
*/
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
misoc_savestate(tcb->xcp.regs);
|
||||
|
||||
up_current_regs()[REG_EPC] = (uint32_t)lm32_sigdeliver;
|
||||
up_current_regs()[REG_INT_CTX] = 0;
|
||||
|
||||
/* And make sure that the saved context in the TCB
|
||||
* is the same as the interrupt return context.
|
||||
*/
|
||||
|
||||
misoc_savestate(tcb->xcp.regs);
|
||||
|
||||
sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_status,
|
||||
up_current_regs()[REG_EPC],
|
||||
up_current_regs()[REG_STATUS]);
|
||||
}
|
||||
sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_status,
|
||||
up_current_regs()[REG_EPC],
|
||||
up_current_regs()[REG_STATUS]);
|
||||
}
|
||||
|
||||
/* Otherwise, we are (1) signaling a task is not running
|
||||
|
||||
@@ -89,58 +89,31 @@ void up_schedule_sigaction(struct tcb_s *tcb)
|
||||
|
||||
if (tcb == this_task())
|
||||
{
|
||||
/* CASE 1: We are not in an interrupt handler and a task is
|
||||
* signalling itself for some reason.
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
if (!up_current_regs())
|
||||
{
|
||||
/* In this case just deliver the signal now. */
|
||||
tcb->xcp.saved_epc = up_current_regs()[REG_CSR_MEPC];
|
||||
|
||||
(tcb->sigdeliver)(tcb);
|
||||
tcb->sigdeliver = NULL;
|
||||
}
|
||||
|
||||
/* CASE 2: We are in an interrupt handler AND the interrupted task
|
||||
* is the same as the one that must receive the signal, then we
|
||||
* will have to modify the return state as well as the state in
|
||||
* the TCB.
|
||||
*
|
||||
* Hmmm... there looks like a latent bug here: The following logic
|
||||
* would fail in the strange case where we are in an interrupt
|
||||
* handler, the thread is signalling itself, but a context switch
|
||||
* to another task has occurred so that g_current_regs does not
|
||||
* refer to the thread of this_task()!
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
up_current_regs()[REG_CSR_MEPC] =
|
||||
(uint32_t)minerva_sigdeliver;
|
||||
up_current_regs()[REG_CSR_MSTATUS] &= ~CSR_MSTATUS_MIE;
|
||||
|
||||
tcb->xcp.saved_epc = up_current_regs()[REG_CSR_MEPC];
|
||||
/* And make sure that the saved context in the TCB is the same
|
||||
* as the interrupt return context.
|
||||
*/
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
misoc_savestate(tcb->xcp.regs);
|
||||
|
||||
up_current_regs()[REG_CSR_MEPC] =
|
||||
(uint32_t)minerva_sigdeliver;
|
||||
up_current_regs()[REG_CSR_MSTATUS] &= ~CSR_MSTATUS_MIE;
|
||||
|
||||
/* And make sure that the saved context in the TCB is the same
|
||||
* as the interrupt return context.
|
||||
*/
|
||||
|
||||
misoc_savestate(tcb->xcp.regs);
|
||||
|
||||
sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_status,
|
||||
up_current_regs()[REG_CSR_MEPC],
|
||||
up_current_regs()[REG_CSR_MSTATUS]);
|
||||
}
|
||||
sinfo("PC/STATUS Saved: %08x/%08x New: %08x/%08x\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_status,
|
||||
up_current_regs()[REG_CSR_MEPC],
|
||||
up_current_regs()[REG_CSR_MSTATUS]);
|
||||
}
|
||||
|
||||
/* Otherwise, we are (1) signaling a task is not running from an
|
||||
|
||||
Reference in New Issue
Block a user