static void handle_ktask_error(rtswitch_context_t *ctx, unsigned fp_val) { unsigned i; ctx->failed = 1; ctx->error.fp_val = fp_val; for (i = 0; i < ctx->tasks_count; i++) { rtswitch_task_t *task = &ctx->tasks[i]; /* Find the first non kernel-space task. */ if ((task->base.flags & RTSWITCH_KERNEL)) continue; /* Unblock it. */ switch(task->base.flags & RTSWITCH_RT) { case RTSWITCH_NRT: rtswitch_utask[ctx->cpu] = task; rtdm_nrtsig_pend(&rtswitch_wake_utask); break; case RTSWITCH_RT: rtdm_event_signal(&task->rt_synch); break; } xnpod_suspend_self(); } }
u_long t_suspend(u_long tid) { u_long err = SUCCESS; psostask_t *task; spl_t s; if (tid == 0) { if (xnpod_unblockable_p()) return -EPERM; xnpod_suspend_self(); if (xnthread_test_info(&psos_current_task()->threadbase, XNBREAK)) return -EINTR; return SUCCESS; } xnlock_get_irqsave(&nklock, s); task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t); if (!task) { err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t); goto unlock_and_exit; } if (xnthread_test_state(&task->threadbase, XNSUSP)) { err = ERR_SUSP; /* Task already suspended. */ goto unlock_and_exit; } xnpod_suspend_thread(&task->threadbase, XNSUSP, XN_INFINITE, XN_RELATIVE, NULL); if (xnthread_test_info(&task->threadbase, XNBREAK)) err = -EINTR; unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }