ER tloc_mtx(ID mtxid, TMO tmout) { MTXCB *p_mtxcb; WINFO_MTX winfo_mtx; TMEVTB tmevtb; ER ercd; LOG_TLOC_MTX_ENTER(mtxid, tmout); CHECK_DISPATCH(); CHECK_ID(VALID_MTXID(mtxid)); CHECK_PAR(VALID_TMOUT(tmout)); p_mtxcb = get_mtxcb(mtxid); lock_cpu_dsp(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn1)) { ercd = E_OACV; } else if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < p_runtsk->p_dominib->minpriority && VIOLATE_ACPTN(p_runtsk->p_dominib->acvct.acptn2)) { ercd = E_OACV; /*[NGKI5124]*/ } else if (p_runtsk->raster) { ercd = E_RASTER; } else if (MTX_CEILING(p_mtxcb) && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) { ercd = E_ILUSE; } else if (p_mtxcb->p_loctsk == NULL) { mutex_acquire(p_runtsk, p_mtxcb); /* * 優先度上限ミューテックスをロックした場合,p_runtskの優先度 * が上がる可能性があるが,ディスパッチが必要になることはない. */ assert(p_runtsk == p_schedtsk); ercd = E_OK; } else if (p_mtxcb->p_loctsk == p_runtsk) { ercd = E_OBJ; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { wobj_make_wait_tmout((WOBJCB *) p_mtxcb, TS_WAITING_MTX, (WINFO_WOBJ *) &winfo_mtx, &tmevtb, tmout); dispatch(); ercd = winfo_mtx.winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_TLOC_MTX_LEAVE(ercd); return(ercd); }
ER ref_mtx(ID mtxid, T_RMTX *pk_rmtx) { MTXCB *p_mtxcb; ER ercd; LOG_REF_MTX_ENTER(mtxid, pk_rmtx); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_MTXID(mtxid)); CHECK_MACV_WRITE(pk_rmtx, T_RMTX); p_mtxcb = get_mtxcb(mtxid); lock_cpu(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn4)) { ercd = E_OACV; } else { pk_rmtx->htskid = (p_mtxcb->p_loctsk != NULL) ? TSKID(p_mtxcb->p_loctsk) : TSK_NONE; pk_rmtx->wtskid = wait_tskid(&(p_mtxcb->wait_queue)); ercd = E_OK; } unlock_cpu(); error_exit: LOG_REF_MTX_LEAVE(ercd, pk_rmtx); return(ercd); }
ER sac_mtx(ID mtxid, const ACVCT *p_acvct) { MTXCB *p_mtxcb; MTXINIB *p_mtxinib; ER ercd; LOG_SAC_MTX_ENTER(mtxid, p_acvct); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_MTXID(mtxid)); CHECK_MACV_READ(p_acvct, ACVCT); p_mtxcb = get_mtxcb(mtxid); lock_cpu(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn3)) { ercd = E_OACV; } else if (MTXID(p_mtxcb) <= tmax_smtxid) { ercd = E_OBJ; } else { p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib); p_mtxinib->acvct = *p_acvct; ercd = E_OK; } unlock_cpu(); error_exit: LOG_SAC_MTX_LEAVE(ercd); return(ercd); }
ER ploc_mtx(ID mtxid) { MTXCB *p_mtxcb; ER ercd; LOG_PLOC_MTX_ENTER(mtxid); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_MTXID(mtxid)); p_mtxcb = get_mtxcb(mtxid); lock_cpu(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn1)) { ercd = E_OACV; } else if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < p_runtsk->p_dominib->minpriority && VIOLATE_ACPTN(p_runtsk->p_dominib->acvct.acptn2)) { ercd = E_OACV; /*[NGKI5124]*/ } else if (MTX_CEILING(p_mtxcb) && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) { ercd = E_ILUSE; } else if (p_mtxcb->p_loctsk == NULL) { mutex_acquire(p_runtsk, p_mtxcb); /* * 優先度上限ミューテックスをロックした場合,p_runtskの優先度 * が上がる可能性があるが,ディスパッチが必要になることはない. */ assert(p_runtsk == p_schedtsk); ercd = E_OK; } else if (p_mtxcb->p_loctsk == p_runtsk) { ercd = E_OBJ; } else { ercd = E_TMOUT; } unlock_cpu(); error_exit: LOG_PLOC_MTX_LEAVE(ercd); return(ercd); }
ER ini_mtx(ID mtxid) { MTXCB *p_mtxcb, **pp_prevmtx; TCB *p_loctsk; ER ercd; LOG_INI_MTX_ENTER(mtxid); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_MTXID(mtxid)); p_mtxcb = get_mtxcb(mtxid); lock_cpu(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn3)) { ercd = E_OACV; } else { init_wait_queue(&(p_mtxcb->wait_queue)); p_loctsk = p_mtxcb->p_loctsk; if (p_loctsk != NULL) { p_mtxcb->p_loctsk = NULL; pp_prevmtx = &(p_loctsk->p_lastmtx); while (*pp_prevmtx != NULL) { if (*pp_prevmtx == p_mtxcb) { *pp_prevmtx = p_mtxcb->p_prevmtx; break; } pp_prevmtx = &((*pp_prevmtx)->p_prevmtx); } mutex_drop_priority(p_loctsk, p_mtxcb); } if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } unlock_cpu(); error_exit: LOG_INI_MTX_LEAVE(ercd); return(ercd); }
ER del_mtx(ID mtxid) { MTXCB *p_mtxcb; MTXINIB *p_mtxinib; const DOMINIB *p_dominib; ER ercd; LOG_DEL_MTX_ENTER(mtxid); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_MTXID(mtxid)); p_mtxcb = get_mtxcb(mtxid); lock_cpu(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn3)) { ercd = E_OACV; } else if (MTXID(p_mtxcb) <= tmax_smtxid) { ercd = E_OBJ; } else { init_wait_queue(&(p_mtxcb->wait_queue)); p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib); p_dominib = get_atrdominib(p_mtxinib->mtxatr); p_mtxinib->mtxatr = TA_NOEXS; queue_insert_prev(&(p_dominib->p_domcb->free_mtxcb), &(p_mtxcb->wait_queue)); if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } unlock_cpu(); error_exit: LOG_DEL_MTX_LEAVE(ercd); return(ercd); }
ER unl_mtx(ID mtxid) { MTXCB *p_mtxcb; ER ercd; LOG_UNL_MTX_ENTER(mtxid); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_MTXID(mtxid)); p_mtxcb = get_mtxcb(mtxid); lock_cpu(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn1)) { ercd = E_OACV; } else if (p_mtxcb != p_runtsk->p_lastmtx) { ercd = E_OBJ; } else { p_runtsk->p_lastmtx = p_mtxcb->p_prevmtx; mutex_drop_priority(p_runtsk, p_mtxcb); mutex_release(p_mtxcb); if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } unlock_cpu(); error_exit: LOG_UNL_MTX_LEAVE(ercd); return(ercd); }
/* * ミューテックス毎の検査 */ static ER bit_mutex_mutex(ID mtxid) { MTXCB *p_mtxcb, *p_acquired_mtx; const MTXINIB *p_mtxinib; TCB *p_tcb; QUEUE *p_queue, *p_next; uint_t pri; if (!VALID_MTXID(mtxid)) { return(E_ID); } p_mtxcb = get_mtxcb(mtxid); p_mtxinib = p_mtxcb->p_mtxinib; /* * 初期化ブロックへのポインタの検査 */ if (p_mtxinib != &(mtxinib_table[INDEX_MTX(mtxid)])) { return(E_SYS_LINENO); } /* * ミューテックス待ちキューの検査 */ p_queue = p_mtxcb->wait_queue.p_next; if (p_queue->p_prev != &(p_mtxcb->wait_queue)) { return(E_SYS_LINENO); } pri = TMIN_TPRI; while (p_queue != &(p_mtxcb->wait_queue)) { p_tcb = (TCB *) p_queue; if (!VALID_TCB(p_tcb)) { return(E_SYS_LINENO); } /* * キューがタスク優先度順になっているかの検査 */ if (MTXPROTO(p_mtxinib) != TA_NULL) { if (p_tcb->priority < pri) { return(E_SYS_LINENO); } } pri = p_tcb->priority; /* * タスク状態の検査 * * ミューテックス待ち状態のタスクの検査は,タスク毎の検査で行っ * ているため,ここでは行わない. */ if (!TSTAT_WAIT_MTX(p_tcb->tstat)) { return(E_SYS_LINENO); } /* * 優先度上限の検査 */ if (MTX_CEILING(p_mtxinib)) { if (p_tcb->bpriority < p_mtxinib->ceilpri) { return(E_SYS_LINENO); } } /* * キューの次の要素に進む */ p_next = p_queue->p_next; if (p_next->p_prev != p_queue) { return(E_SYS_LINENO); } p_queue = p_next; } /* * ミューテックスをロックしているタスクの検査 */ p_tcb = p_mtxcb->p_loctsk; if (p_tcb == NULL) { /* * ミューテックスがロックされていない時 */ if (!queue_empty(&(p_mtxcb->wait_queue))) { return(E_SYS_LINENO); } } else { /* * ミューテックスがロックされている時 * * ミューテックスをロックしているタスクの検査は,タスク毎の検 * 査で行っているため,ここでは行わない. */ if (!VALID_TCB(p_tcb)) { return(E_SYS_LINENO); } p_acquired_mtx = p_tcb->p_lastmtx; while (p_mtxcb != NULL) { if (p_mtxcb == p_acquired_mtx) { break; } p_acquired_mtx = p_acquired_mtx->p_prevmtx; } if (p_mtxcb == NULL) { return(E_SYS_LINENO); } /* * 優先度上限の検査 */ if (MTX_CEILING(p_mtxinib)) { if (p_tcb->bpriority < p_mtxinib->ceilpri) { return(E_SYS_LINENO); } } } return(E_OK); }