void wobj_change_priority(WOBJCB *wobjcb, TCB *tcb) { if ((wobjcb->wobjinib->wobjatr & TA_TPRI) != 0) { queue_delete(&(tcb->task_queue)); queue_insert_tpri(tcb, &(wobjcb->wait_queue)); } }
/* * 実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入 * * 実行中のタスクを,同期・通信オブジェクトの待ちキューへ挿入する.オ * ブジェクトの属性に応じて,FIFO順またはタスク優先度順で挿入する. */ Inline void wobj_queue_insert(WOBJCB *p_wobjcb) { if ((p_wobjcb->p_wobjinib->wobjatr & TA_TPRI) != 0U) { queue_insert_tpri(&(p_wobjcb->wait_queue), p_runtsk); } else { queue_insert_prev(&(p_wobjcb->wait_queue), &(p_runtsk->task_queue)); } }
/* * 実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入 */ Inline void wobj_queue_insert(WOBJCB *wobjcb) { if ((wobjcb->wobjinib->wobjatr & TA_TPRI) != 0) { queue_insert_tpri(runtsk, &(wobjcb->wait_queue)); } else { queue_insert_prev(&(wobjcb->wait_queue), &(runtsk->task_queue)); } }
/* * Forward Rendezvous to Other Port */ SYSCALL ER _tk_fwd_por( ID porid, UINT calptn, RNO rdvno, void *msg, INT cmsgsz ) { PORCB *porcb; TCB *caltcb, *tcb; QUEUE *queue; RNO new_rdvno; ER ercd = E_OK; CHECK_PORID(porid); CHECK_PAR(calptn != 0); CHECK_RDVNO(rdvno); CHECK_PAR(cmsgsz >= 0); CHECK_INTSK(); porcb = get_porcb(porid); caltcb = get_tcb(get_tskid_rdvno(rdvno)); BEGIN_CRITICAL_SECTION; if ( porcb->porid == 0 ) { ercd = E_NOEXS; goto error_exit; } #if CHK_PAR if ( cmsgsz > porcb->maxcmsz ) { ercd = E_PAR; goto error_exit; } #endif if ( (caltcb->state & TS_WAIT) == 0 || caltcb->wspec != &wspec_rdv || rdvno != caltcb->winfo.rdv.rdvno ) { ercd = E_OBJ; goto error_exit; } if ( porcb->maxrmsz > caltcb->winfo.rdv.maxrmsz ) { ercd = E_OBJ; goto error_exit; } #if CHK_PAR if ( cmsgsz > caltcb->winfo.rdv.maxrmsz ) { ercd = E_PAR; goto error_exit; } #endif /* Search accept wait task */ queue = porcb->accept_queue.next; while ( queue != &porcb->accept_queue ) { tcb = (TCB*)queue; queue = queue->next; if ( (calptn & tcb->winfo.acp.acpptn) == 0 ) { continue; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_CAL) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Send message */ new_rdvno = gen_rdvno(caltcb); if ( cmsgsz > 0 ) { memcpy(tcb->winfo.acp.msg, msg, (UINT)cmsgsz); } *tcb->winfo.acp.p_rdvno = new_rdvno; *tcb->winfo.acp.p_cmsgsz = cmsgsz; wait_release_ok(tcb); /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_RDV) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Change rendezvous end wait of the other task */ caltcb->winfo.rdv.rdvno = new_rdvno; caltcb->winfo.rdv.msg = caltcb->winfo.cal.msg; caltcb->winfo.rdv.maxrmsz = porcb->maxrmsz; caltcb->winfo.rdv.p_rmsgsz = caltcb->winfo.cal.p_rmsgsz; caltcb->nodiswai = ( (porcb->poratr & TA_NODISWAI) != 0 )? TRUE: FALSE; goto error_exit; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_CAL) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Change the other task to rendezvous call wait */ caltcb->wspec = ( (porcb->poratr & TA_TPRI) != 0 )? &wspec_cal_tpri: &wspec_cal_tfifo; caltcb->wid = porid; caltcb->winfo.cal.calptn = calptn; caltcb->winfo.cal.msg = caltcb->winfo.rdv.msg; caltcb->winfo.cal.cmsgsz = cmsgsz; caltcb->winfo.cal.p_rmsgsz = caltcb->winfo.rdv.p_rmsgsz; caltcb->nodiswai = ( (porcb->poratr & TA_NODISWAI) != 0 )? TRUE: FALSE; timer_insert(&caltcb->wtmeb, TMO_FEVR, (CBACK)wait_release_tmout, caltcb); if ( (porcb->poratr & TA_TPRI) != 0 ) { queue_insert_tpri(caltcb, &porcb->call_queue); } else { QueInsert(&caltcb->tskque, &porcb->call_queue); } if ( cmsgsz > 0 ) { memcpy(caltcb->winfo.cal.msg, msg, (UINT)cmsgsz); } error_exit: END_CRITICAL_SECTION; return ercd; }
SYSCALL ER _tk_loc_mtx_u( ID mtxid, TMO_U tmout ) { MTXCB *mtxcb; TCB *mtxtsk; ATR mtxatr; ER ercd = E_OK; CHECK_MTXID(mtxid); CHECK_TMOUT(tmout); CHECK_DISPATCH(); mtxcb = get_mtxcb(mtxid); BEGIN_CRITICAL_SECTION; if ( mtxcb->mtxid == 0 ) { ercd = E_NOEXS; goto error_exit; } if ( mtxcb->mtxtsk == ctxtsk ) { ercd = E_ILUSE; /* Multiplexed lock */ goto error_exit; } mtxatr = mtxcb->mtxatr & TA_CEILING; if ( mtxatr == TA_CEILING ) { if ( ctxtsk->bpriority < mtxcb->ceilpri ) { /* Violation of highest priority limit */ ercd = E_ILUSE; goto error_exit; } } /* Check wait disable */ if ( is_diswai((GCB*)mtxcb, ctxtsk, TTW_MTX) ) { ercd = E_DISWAI; goto error_exit; } mtxtsk = mtxcb->mtxtsk; if ( mtxtsk == NULL ) { /* Get lock */ mtxcb->mtxtsk = ctxtsk; mtxcb->mtxlist = ctxtsk->mtxlist; ctxtsk->mtxlist = mtxcb; if ( mtxatr == TA_CEILING ) { if ( ctxtsk->priority > mtxcb->ceilpri ) { /* Raise its own task to the highest priority limit */ change_task_priority(ctxtsk, mtxcb->ceilpri); } } } else { ercd = E_TMOUT; if ( tmout == TMO_POL ) { goto error_exit; } if ( mtxatr == TA_INHERIT ) { if ( mtxtsk->priority > ctxtsk->priority ) { /* Raise the priority of task during locking to the same priority as its own task */ change_task_priority(mtxtsk, ctxtsk->priority); } } /* Ready for wait */ ctxtsk->wspec = ( mtxatr == TA_TFIFO )? &wspec_mtx_tfifo: ( mtxatr == TA_INHERIT )? &wspec_mtx_inherit: &wspec_mtx_tpri; ctxtsk->wercd = &ercd; ctxtsk->wid = mtxcb->mtxid; make_wait(tmout, mtxcb->mtxatr); if ( mtxatr == TA_TFIFO ) { QueInsert(&ctxtsk->tskque, &mtxcb->wait_queue); } else { queue_insert_tpri(ctxtsk, &mtxcb->wait_queue); } } error_exit: END_CRITICAL_SECTION; return ercd; }