void up_sigdeliver(void) { struct tcb_s *rtcb = this_task(); uint32_t regs[XCPTCONTEXT_REGS]; sig_deliver_t sigdeliver; /* Save the errno. This must be preserved throughout the signal handling * so that the user code final gets the correct errno value (probably * EINTR). */ int saved_errno = rtcb->pterrno; board_autoled_on(LED_SIGNAL); svdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); ASSERT(rtcb->xcp.sigdeliver != NULL); /* Save the real return state on the stack. */ up_copyfullstate(regs, rtcb->xcp.regs); regs[REG_PC] = rtcb->xcp.saved_pc; regs[REG_CPSR] = rtcb->xcp.saved_cpsr; /* Get a local copy of the sigdeliver function pointer. we do this so that * we can nullify the sigdeliver function pointer in the TCB and accept * more signal deliveries while processing the current pending signals. */ sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; /* Then restore the task interrupt state */ irqrestore(regs[REG_CPSR]); /* Deliver the signals */ 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). */ svdbg("Resuming\n"); (void)irqsave(); rtcb->pterrno = saved_errno; /* Then restore the correct state for this thread of execution. */ board_autoled_off(LED_SIGNAL); #ifdef CONFIG_TASK_SCHED_HISTORY /* Save the task name which will be scheduled */ save_task_scheduling_status(rtcb); #endif up_fullcontextrestore(regs); }
void up_sigdeliver(void) { /* NOTE the "magic" guard space added to regs. This is a little kludge * because up_fullcontextrestore (called below) will do a stack-to-stack * copy an may overwrite the regs[] array contents. Sorry. */ struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; uint32_t regs[XCPTCONTEXT_REGS + 4]; sig_deliver_t sigdeliver; /* Save the errno. This must be preserved throughout the signal handling * so that the user code final gets the correct errno value (probably * EINTR). */ int saved_errno = rtcb->pterrno; board_led_on(LED_SIGNAL); sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); ASSERT(rtcb->xcp.sigdeliver != NULL); /* Save the real return state on the stack. */ up_copyfullstate(regs, rtcb->xcp.regs); regs[REG_PC] = rtcb->xcp.saved_pc; regs[REG_PRIMASK] = rtcb->xcp.saved_primask; regs[REG_XPSR] = rtcb->xcp.saved_xpsr; #ifdef CONFIG_BUILD_PROTECTED regs[REG_LR] = rtcb->xcp.saved_lr; #endif /* Get a local copy of the sigdeliver function pointer. We do this so that * we can nullify the sigdeliver function pointer in the TCB and accept * more signal deliveries while processing the current pending signals. */ sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; /* Then restore the task interrupt state */ irqrestore((uint8_t)regs[REG_PRIMASK]); /* 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). */ sdbg("Resuming\n"); (void)irqsave(); rtcb->pterrno = saved_errno; /* Then restore the correct state for this thread of * execution. */ board_led_off(LED_SIGNAL); up_fullcontextrestore(regs); }
void up_sigdeliver(void) { struct tcb_s *rtcb = this_task(); uint32_t regs[XCPTCONTEXT_REGS]; sig_deliver_t sigdeliver; /* Save the errno. This must be preserved throughout the signal handling * so that the user code final gets the correct errno value (probably * EINTR). */ int saved_errno = rtcb->pterrno; board_autoled_on(LED_SIGNAL); sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); ASSERT(rtcb->xcp.sigdeliver != NULL); /* Save the real return state on the stack. */ up_copyfullstate(regs, rtcb->xcp.regs); regs[REG_PC] = rtcb->xcp.saved_pc; #ifdef CONFIG_ARMV7M_USEBASEPRI regs[REG_BASEPRI] = rtcb->xcp.saved_basepri; #else regs[REG_PRIMASK] = rtcb->xcp.saved_primask; #endif regs[REG_XPSR] = rtcb->xcp.saved_xpsr; #ifdef CONFIG_BUILD_PROTECTED regs[REG_LR] = rtcb->xcp.saved_lr; #endif /* Get a local copy of the sigdeliver function pointer. We do this so that * we can nullify the sigdeliver function pointer in the TCB and accept * more signal deliveries while processing the current pending signals. */ sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; /* Then restore the task interrupt state */ #ifdef CONFIG_ARMV7M_USEBASEPRI irqrestore((uint8_t)regs[REG_BASEPRI]); #else irqrestore((uint16_t)regs[REG_PRIMASK]); #endif /* 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). */ sdbg("Resuming\n"); (void)irqsave(); rtcb->pterrno = saved_errno; /* Then restore the correct state for this thread of * execution. */ board_autoled_off(LED_SIGNAL); up_fullcontextrestore(regs); }