Skip to content

Commit

Permalink
signal: adjust the signal processing logic to remove the judgment
Browse files Browse the repository at this point in the history
Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 committed Sep 30, 2024
1 parent bddf6b6 commit 6111d95
Show file tree
Hide file tree
Showing 33 changed files with 1,902 additions and 2,131 deletions.
89 changes: 41 additions & 48 deletions arch/arm/src/arm/arm_schedulesigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,70 +75,63 @@
*
****************************************************************************/

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\n", tcb);

/* 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)
{
tcb->sigdeliver = sigdeliver;

/* First, handle some special cases when the signal is
* being delivered to the currently executing task.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(),
this_task()->xcp.regs);

sinfo("rtcb=%p current_regs=%p\n", this_task(),
this_task()->xcp.regs);
if (tcb == this_task() && !up_interrupt_context())
{
/* In this case just deliver the signal now. */

if (tcb == this_task() && !up_interrupt_context())
{
/* In this case just deliver the signal now. */
((sig_deliver_t)tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}

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.
*/

/* 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.
*/

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 current register context location */
/* Save the current register context location */

tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;

/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/

tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);

tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;

/* Then set up to vector to the trampoline with interrupts
* disabled
*/
/* Then set up to vector to the trampoline with interrupts
* disabled
*/

tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT;
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT;
#ifdef CONFIG_ARM_THUMB
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
#endif
}
}
}
137 changes: 65 additions & 72 deletions arch/arm/src/armv6-m/arm_schedulesigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,103 +78,96 @@
*
****************************************************************************/

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);
DEBUGASSERT(tcb != NULL && sigdeliver != NULL);
sinfo("tcb=%p\n", tcb);
DEBUGASSERT(tcb != NULL);

/* 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 == NULL)
{
tcb->sigdeliver = sigdeliver;
sinfo("rtcb=%p current_regs=%p\n", this_task(),
this_task()->xcp.regs);

/* First, handle some special cases when the signal is being delivered
* to the currently executing task.
if (tcb == this_task() && !up_interrupt_context())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/

sinfo("rtcb=%p current_regs=%p\n", this_task(),
this_task()->xcp.regs);

if (tcb == this_task() && !up_interrupt_context())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handle will run in a critical section!
*/
((sig_deliver_t)tcb->sigdeliver)(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/

sigdeliver(tcb);
tcb->sigdeliver = NULL;
}
else
{
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/

/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/

#ifdef CONFIG_SMP
int cpu = tcb->cpu;
int me = this_cpu();
int cpu = tcb->cpu;
int me = this_cpu();

if (cpu != me && tcb->task_state == TSTATE_TASK_RUNNING)
{
/* Pause the CPU */
if (cpu != me && tcb->task_state == TSTATE_TASK_RUNNING)
{
/* Pause the CPU */

up_cpu_pause(cpu);
}
up_cpu_pause(cpu);
}
#endif

/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/
/* Save the return PC, CPSR and either the BASEPRI or PRIMASK
* registers (and perhaps also the LR). These will be restored
* by the signal trampoline after the signal has been delivered.
*/

/* Save the current register context location */
/* Save the current register context location */

tcb->xcp.saved_regs = tcb->xcp.regs;
tcb->xcp.saved_regs = tcb->xcp.regs;

/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/
/* Duplicate the register context. These will be
* restored by the signal trampoline after the signal has been
* delivered.
*/

tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
tcb->xcp.regs = (void *)
((uint32_t)tcb->xcp.regs -
XCPTCONTEXT_SIZE);
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);

tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->xcp.regs +
XCPTCONTEXT_SIZE;

/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/
/* Then set up to vector to the trampoline with interrupts
* disabled. We must already be in privileged thread mode to be
* here.
*/

tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif

#ifdef CONFIG_SMP
/* RESUME the other CPU if it was PAUSED */
/* RESUME the other CPU if it was PAUSED */

if (cpu != me && tcb->task_state == TSTATE_TASK_RUNNING)
{
up_cpu_resume(cpu);
}
#endif
if (cpu != me && tcb->task_state == TSTATE_TASK_RUNNING)
{
up_cpu_resume(cpu);
}
#endif
}
}
Loading

0 comments on commit 6111d95

Please sign in to comment.