void _exit(int status) { _TCB* tcb; /* Disable interrupts. They will be restored when the next * task is started. */ (void)irqsave(); slldbg("TCB=%p exitting\n", g_readytorun.head); #if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) slldbg("Other tasks:\n"); sched_foreach(_up_dumponexit, NULL); #endif /* Destroy the task at the head of the ready to run list. */ (void)task_deletecurrent(); /* Now, perform the context switch to the new ready-to-run task at the * head of the list. */ tcb = (_TCB*)g_readytorun.head; /* Then switch contexts */ up_fullcontextrestore(tcb->xcp.regs); }
void _exit(int status) { FAR struct tcb_s* tcb; /* Disable interrupts. Interrupts will remain disabled until * the new task is resumed below. */ (void)irqsave(); slldbg("TCB=%p exitting\n", tcb); #if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG) lldbg("Other tasks:\n"); sched_foreach(_up_dumponexit, NULL); #endif /* Destroy the task at the head of the ready to run list. */ (void)task_deletecurrent(); /* Now, perform the context switch to the new ready-to-run task at the * head of the list. */ tcb = (FAR struct tcb_s*)g_readytorun.head; slldbg("New Active Task TCB=%p\n", tcb); /* Then switch contexts */ RESTORE_USERCONTEXT(tcb); }
void _exit(int status) { struct tcb_s* tcb; sdbg("TCB=%p exitting\n", tcb); /* Destroy the task at the head of the ready to run list. */ (void)task_deletecurrent(); /* Now, perform the context switch to the new ready-to-run task at the * head of the list. */ tcb = (struct tcb_s*)g_readytorun.head; sdbg("New Active Task TCB=%p\n", tcb); /* The way that we handle signals in the simulation is kind of * a kludge. This would be unsafe in a truly multi-threaded, interrupt * driven environment. */ if (tcb->xcp.sigdeliver) { sdbg("Delivering signals TCB=%p\n", tcb); ((sig_deliver_t)tcb->xcp.sigdeliver)(tcb); tcb->xcp.sigdeliver = NULL; } /* Then switch contexts */ up_longjmp(tcb->xcp.regs, 1); }