예제 #1
0
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);
}
예제 #3
0
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);
}