/* * Wakeup task */ SYSCALL ER _tk_wup_tsk( ID tskid ) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; state = (TSTAT)tcb->state; if ( !task_alive(state) ) { ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; } else if ( (state & TS_WAIT) != 0 && tcb->wspec == &wspec_slp ) { wait_release_ok(tcb); } else if ( tcb->wupcnt == INT_MAX ) { ercd = E_QOVR; } else { ++tcb->wupcnt; } END_CRITICAL_SECTION; return ercd; }
/* * Get task coprocessor register */ SYSCALL ER _tk_get_cpr( ID tskid, INT copno, T_COPREGS *pk_copregs ) { ATR copatr = TA_COP0 << copno; TCB *tcb; ER ercd = E_OK; CHECK_INTSK(); CHECK_TSKID(tskid); CHECK_NONSELF(tskid); CHECK_PAR((copatr & available_cop) != 0); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else { ercd = mp_check_domain_and_protection(tskid, tcb->tskid, tcb->tskatr); if ( ercd == E_OK ) { if ( (tcb->tskatr & copatr) == 0 ) { ercd = E_PAR; } else if ( is_ctxtsk(tcb) ) { ercd = E_OBJ; } else { /* No coprocessor */ } } } END_CRITICAL_NO_DISPATCH; return ercd; }
/* * Termination of other task */ SYSCALL ER _tk_ter_tsk( ID tskid ) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; state = (TSTAT)tcb->state; if ( !task_alive(state) ) { ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; } else if ( tcb->klocked ) { /* Normally, it does not become this state. * When the state is page-in wait in the virtual memory * system and when trying to terminate any task, * it becomes this state. */ ercd = E_OBJ; } else { _ter_tsk(tcb); make_dormant(tcb); } END_CRITICAL_SECTION; return ercd; }
/* * Get task register contents */ SYSCALL ER _tk_get_reg( ID tskid, T_REGS *pk_regs, T_EIT *pk_eit, T_CREGS *pk_cregs ) { TCB *tcb; ER ercd = E_OK; CHECK_INTSK(); CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else { ercd = mp_check_domain_and_protection(tskid, tcb->tskid, tcb->tskatr); if ( ercd == E_OK ) { if ( is_ctxtsk(tcb) ) { ercd = E_OBJ; } else { get_reg(tcb, pk_regs, pk_eit, pk_cregs); } } } END_CRITICAL_NO_DISPATCH; return ercd; }
/* * Set task register */ SYSCALL ER _td_set_reg( ID tskid, T_REGS *regs, T_EIT *eit, T_CREGS *cregs ) { TCB *tcb; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); #if 0 /* (030206) This is not an error. Please ignore. */ if ( eit != NULL ) { if ( (eit->sr & (SR_BL|SR_I(15))) != 0 ) { return E_PAR; } } #endif tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else if ( !MP_CMP_DOMIDPART(tskid, tcb->tskid) ) { ercd = E_NOEXS; } else if ( is_ctxtsk(tcb) ) { ercd = E_OBJ; } else { set_reg(tcb, regs, eit, cregs); } END_CRITICAL_NO_DISPATCH; return ercd; }
ER ter_tsk(ID tskid) { TCB *p_tcb; bool_t dspreq = false; ER ercd; LOG_TER_TSK_ENTER(tskid); CHECK_TSKCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); CHECK_NONSELF(p_tcb); t_lock_cpu(); if (p_tcb->p_tinib->tskatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_tcb->p_tinib->acvct.acptn2)) { ercd = E_OACV; } else if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; } else { if (TSTAT_RUNNABLE(p_tcb->tstat)) { /* * p_tcbは自タスクでないため,(シングルプロセッサでは)実 * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ * チが必要になることはない. */ (void) make_non_runnable(p_tcb); } else if (TSTAT_WAITING(p_tcb->tstat)) { wait_dequeue_wobj(p_tcb); wait_dequeue_tmevtb(p_tcb); } if (!queue_empty(&(p_tcb->mutex_queue))) { if ((*mtxhook_release_all)(p_tcb)) { dspreq = true; } } make_dormant(p_tcb); if (p_tcb->actque) { p_tcb->actque = false; if (make_active(p_tcb)) { dspreq = true; } } if (dspreq) { dispatch(); } ercd = E_OK; } t_unlock_cpu(); error_exit: LOG_TER_TSK_LEAVE(ercd); return(ercd); }
ER ter_tsk(ID tskid) { TCB *p_tcb; ER ercd; LOG_TER_TSK_ENTER(tskid); CHECK_TSKCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); CHECK_NONSELF(p_tcb); t_lock_cpu(); if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; } else { if (TSTAT_RUNNABLE(p_tcb->tstat)) { /* * p_tcbは自タスクでないため,(シングルプロセッサでは)実 * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ * チが必要になることはない. */ (void) make_non_runnable(p_tcb); } else if (TSTAT_WAITING(p_tcb->tstat)) { wait_dequeue_wobj(p_tcb); wait_dequeue_tmevtb(p_tcb); } make_dormant(p_tcb); if (p_tcb->actque) { p_tcb->actque = false; if (make_active(p_tcb)) { dispatch(); } } ercd = E_OK; } t_unlock_cpu(); error_exit: LOG_TER_TSK_LEAVE(ercd); return(ercd); }
/* * Suspend task */ SYSCALL ER _tk_sus_tsk( ID tskid ) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; state = (TSTAT)tcb->state; if ( !task_alive(state) ) { ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; goto error_exit; } if ( tcb == ctxtsk && dispatch_disabled >= DDS_DISABLE ) { ercd = E_CTX; goto error_exit; } if ( tcb->suscnt == INT_MAX ) { ercd = E_QOVR; goto error_exit; } /* Update suspend request count */ ++tcb->suscnt; /* Move to forced wait state */ if ( state == TS_READY ) { make_non_ready(tcb); tcb->state = TS_SUSPEND; } else if ( state == TS_WAIT ) { tcb->state = TS_WAITSUS; } error_exit: END_CRITICAL_SECTION; return ercd; }
/* * Resume task */ SYSCALL ER _tk_rsm_tsk( ID tskid ) { TCB *tcb; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; switch ( tcb->state ) { case TS_NONEXIST: ercd = E_NOEXS; break; case TS_DORMANT: case TS_READY: case TS_WAIT: ercd = E_OBJ; break; case TS_SUSPEND: if ( --tcb->suscnt == 0 ) { make_ready(tcb); } break; case TS_WAITSUS: if ( --tcb->suscnt == 0 ) { tcb->state = TS_WAIT; } break; default: ercd = E_SYS; break; } END_CRITICAL_SECTION; return ercd; }
/* * Get task register contents */ SYSCALL ER tk_get_reg_impl( ID tskid, T_REGS *pk_regs, T_EIT *pk_eit, T_CREGS *pk_cregs ) { TCB *tcb; ER ercd = E_OK; CHECK_INTSK(); CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else { knl_get_reg(tcb, pk_regs, pk_eit, pk_cregs); } END_CRITICAL_SECTION; return ercd; }
/* * Delete task */ SYSCALL ER _tk_del_tsk( ID tskid ) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; state = (TSTAT)tcb->state; if ( state != TS_DORMANT ) { ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; } else { _del_tsk(tcb); } END_CRITICAL_SECTION; return ercd; }
SYSCALL ER ter_tsk(ID tskid) { TCB *tcb; UINT tstat; ER ercd; LOG_TER_TSK_ENTER(tskid); CHECK_TSKCTX_UNL(); CHECK_TSKID(tskid); tcb = get_tcb(tskid); CHECK_NONSELF(tcb); t_lock_cpu(); if (TSTAT_DORMANT(tstat = tcb->tstat)) { ercd = E_OBJ; } else { if (TSTAT_RUNNABLE(tstat)) { make_non_runnable(tcb); } else if (TSTAT_WAITING(tstat)) { wait_cancel(tcb); } make_dormant(tcb); if (tcb->actcnt) { tcb->actcnt = FALSE; if (make_active(tcb)) { dispatch(); } } ercd = E_OK; } t_unlock_cpu(); exit: LOG_TER_TSK_LEAVE(ercd); return(ercd); }
/* * Get task coprocessor register */ SYSCALL ER _tk_get_cpr( ID tskid, INT copno, T_COPREGS *pk_copregs ) { ATR copatr = TA_COP0 << copno; TCB *tcb; ER ercd = E_OK; CHECK_INTSK(); CHECK_TSKID(tskid); CHECK_NONSELF(tskid); CHECK_PAR((copatr & available_cop) != 0); tcb = get_tcb(tskid); BEGIN_CRITICAL_NO_DISPATCH; /* Because the state of the task doesn't change. */ if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else { ercd = mp_check_domain_and_protection(tskid, tcb->tskid, tcb->tskatr); if ( ercd == E_OK ) { if ( (tcb->tskatr & copatr) == 0 ) { ercd = E_PAR; } else if ( is_ctxtsk(tcb) ) { ercd = E_OBJ; } else { #if USE_SH3_DSP /* Get DSP register */ memcpy(pk_copregs, tcb->isstack, sizeof(T_COP0REGS)); #endif #if TA_FPU /* Get FPU register */ memcpy(pk_copregs, tcb->isstack, sizeof(T_COP0REGS)); #endif } } } END_CRITICAL_NO_DISPATCH; return ercd; }
SYSCALL ER i_vsnd_tmb(ID tskid,T_MSG *pk_msg) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_TSKACV(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( !task_alive(state = tcb->state) ) { ercd = (state == TS_NONEXIST) ? E_NOEXS : E_OBJ; } else if ((state & TS_WAIT) && tcb->wspec == &wspec_tmb_tfifo) { *(tcb->winfo.tmb.ppk_msg) = pk_msg; wait_release_ok(tcb); } else { nextmsg(pk_msg) = (T_MSG *) 0; if (tcb->tmq_head) { nextmsg(tcb->tmq_tail) = pk_msg; } else { tcb->tmq_head = pk_msg; } tcb->tmq_tail = pk_msg; } END_CRITICAL_SECTION; return(ercd); }
/* * Start task */ SYSCALL ER tk_sta_tsk_impl( ID tskid, INT stacd ) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; state = (TSTAT)tcb->state; if ( state != TS_DORMANT ) { ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ; } else { knl_setup_stacd(tcb, stacd); knl_make_ready(tcb); } END_CRITICAL_SECTION; return ercd; }
/* * Get task register */ SYSCALL ER _td_get_reg( ID tskid, T_REGS *regs, T_EIT *eit, T_CREGS *cregs ) { TCB *tcb; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else if ( !MP_CMP_DOMIDPART(tskid, tcb->tskid) ) { ercd = E_NOEXS; } else if ( is_ctxtsk(tcb) ) { ercd = E_OBJ; } else { get_reg(tcb, regs, eit, cregs); } END_CRITICAL_NO_DISPATCH; return ercd; }