signal: adjust the signal processing logic to remove the judgment

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5
2024-09-09 20:17:25 +08:00
committed by Xiang Xiao
parent 7eea4223ee
commit f132ed2edb
33 changed files with 1938 additions and 2220 deletions
+60 -68
View File
@@ -70,95 +70,87 @@
*
****************************************************************************/
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
void up_schedule_sigaction(struct tcb_s *tcb)
{
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb,
this_task(), up_current_regs());
/* Refuse to handle nested signal actions */
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
*/
if (!tcb->sigdeliver)
if (tcb == this_task())
{
tcb->sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
/* CASE 1: We are not in an interrupt handler and a task is
* signalling itself for some reason.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb == this_task())
if (!up_current_regs())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signalling itself for some reason.
*/
/* In this case just deliver the signal now. */
if (!up_current_regs())
{
/* In this case just deliver the signal now. */
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()!
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
tcb->xcp.saved_eip = up_current_regs()[REG_EIP];
tcb->xcp.saved_eflags = up_current_regs()[REG_EFLAGS];
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
up_current_regs()[REG_EIP] = (uint32_t)x86_sigdeliver;
up_current_regs()[REG_EFLAGS] = 0;
/* And make sure that the saved context in the TCB
* is the same as the interrupt return context.
*/
x86_savestate(tcb->xcp.regs);
}
(tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
/* Otherwise, we are (1) signaling a task is not running
* from an interrupt handler or (2) we are not in an
* interrupt handler and the running task is signalling
* some non-running task.
/* 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()!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
tcb->xcp.saved_eip = tcb->xcp.regs[REG_EIP];
tcb->xcp.saved_eflags = tcb->xcp.regs[REG_EFLAGS];
tcb->xcp.saved_eip = up_current_regs()[REG_EIP];
tcb->xcp.saved_eflags = up_current_regs()[REG_EFLAGS];
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_EIP] = (uint32_t)x86_sigdeliver;
tcb->xcp.regs[REG_EFLAGS] = 0;
up_current_regs()[REG_EIP] = (uint32_t)x86_sigdeliver;
up_current_regs()[REG_EFLAGS] = 0;
/* And make sure that the saved context in the TCB
* is the same as the interrupt return context.
*/
x86_savestate(tcb->xcp.regs);
}
}
/* Otherwise, we are (1) signaling a task is not running
* from an interrupt handler or (2) we are not in an
* interrupt handler and the running task is signalling
* some non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
tcb->xcp.saved_eip = tcb->xcp.regs[REG_EIP];
tcb->xcp.saved_eflags = tcb->xcp.regs[REG_EFLAGS];
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
tcb->xcp.regs[REG_EIP] = (uint32_t)x86_sigdeliver;
tcb->xcp.regs[REG_EFLAGS] = 0;
}
}