/* * タスク毎の検査 */ static ER bit_mutex_task(ID tskid) { TCB *p_tcb; uint_t pri; MTXCB *p_mtxcb; const MTXINIB *p_mtxinib; if (!VALID_TSKID(tskid)) { return(E_ID); } p_tcb = get_tcb(tskid); pri = p_tcb->bpriority; /* * タスクがロックしているミューテックスのキューの検査 */ p_mtxcb = p_tcb->p_lastmtx; while (p_mtxcb != NULL) { if (!VALID_MTXCB(p_mtxcb)) { return(E_SYS_LINENO); } p_mtxinib = p_mtxcb->p_mtxinib; /* * ミューテックスをロックしているタスクのチェック */ if (p_mtxcb->p_loctsk != p_tcb) { return(E_SYS_LINENO); } /* * 現在優先度の計算 */ if (MTXPROTO(p_mtxinib)) { if (p_mtxinib->ceilpri < pri) { pri = p_mtxinib->ceilpri; } } /* * キューの次の要素に進む */ p_mtxcb = p_mtxcb->p_prevmtx; } /* * 現在優先度の検査 */ if (p_tcb->priority != pri) { return(E_SYS_LINENO); } /* * タスクが待っているミューテックスに関する検査 */ if (TSTAT_WAIT_MTX(p_tcb->tstat)) { p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb; if (!VALID_MTXCB(p_mtxcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } } return(E_OK); }
/* * タスク毎の整合性検査 */ static ER bit_task(ID tskid) { TCB *p_tcb; const TINIB *p_tinib; uint_t tstat, tstat_wait, pri; TMEVTB *p_tmevtb; SEMCB *p_semcb; FLGCB *p_flgcb; DTQCB *p_dtqcb; PDQCB *p_pdqcb; MTXCB *p_mtxcb; MPFCB *p_mpfcb; if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) { return(E_ID); } p_tcb = get_tcb(tskid); p_tinib = p_tcb->p_tinib; tstat = p_tcb->tstat; tstat_wait = (tstat & TS_WAIT_MASK); pri = p_tcb->priority; /* * 初期化ブロックへのポインタの検査 */ if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) { return(E_SYS_LINENO); } /* * tstatの検査 */ switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) { case TS_DORMANT: if (tstat != TS_DORMANT) { return(E_SYS_LINENO); } break; case TS_RUNNABLE: if (tstat != TS_RUNNABLE) { return(E_SYS_LINENO); } break; case TS_WAITING: case (TS_WAITING | TS_SUSPENDED): if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MTX) || tstat_wait == TS_WAIT_MBX) { return(E_SYS_LINENO); } if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) != 0U) { return(E_SYS_LINENO); } break; case TS_SUSPENDED: if (tstat != TS_SUSPENDED) { return(E_SYS_LINENO); } break; default: return(E_SYS_LINENO); } /* * actqueの検査 */ if (TSTAT_DORMANT(tstat) && p_tcb->actque) { return(E_SYS_LINENO); } /* * タスク優先度の検査 */ if (pri >= TNUM_TPRI) { return(E_SYS_LINENO); } /* * texptnの検査 */ if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) { return(E_SYS_LINENO); } /* * 休止状態におけるチェック */ if (TSTAT_DORMANT(tstat)) { if (!(pri == p_tinib->ipriority) && (p_tcb->wupque == false) && (p_tcb->enatex == false) && (p_tcb->texptn == 0U)) { return(E_SYS_LINENO); } } /* * 実行できる状態におけるチェック */ if (TSTAT_RUNNABLE(tstat)) { if (!in_queue(&ready_queue[pri], &(p_tcb->task_queue))) { return(E_SYS_LINENO); } } /* * 待ち状態におけるチェック */ if (TSTAT_WAITING(tstat)) { if (!on_stack(p_tcb->p_winfo, p_tinib)) { return(E_SYS_LINENO); } p_tmevtb = p_tcb->p_winfo->p_tmevtb; if (p_tmevtb != NULL) { if (!on_stack(p_tmevtb, p_tinib)) { return(E_SYS_LINENO); } /* * (*p_tmevtb)の検査(未完成) */ } switch (tstat & TS_WAIT_MASK) { case TS_WAIT_SLP: if (p_tcb->wupque == true) { return(E_SYS_LINENO); } break; case TS_WAIT_DLY: if (p_tmevtb == NULL) { return(E_SYS_LINENO); } break; case TS_WAIT_SEM: p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb; if (!VALID_SEMCB(p_semcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_FLG: p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb; if (!VALID_FLGCB(p_flgcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_SDTQ: p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb; if (!VALID_DTQCB(p_dtqcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_RDTQ: p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb; if (!VALID_DTQCB(p_dtqcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_SPDQ: p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb; if (!VALID_PDQCB(p_pdqcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_RPDQ: p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb; if (!VALID_PDQCB(p_pdqcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_MTX: p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb; if (!VALID_MTXCB(p_mtxcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; case TS_WAIT_MPF: p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb; if (!VALID_MPFCB(p_mpfcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } break; } } /* * tskctxbの検査 */ if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) { /* * ターゲット依存の検査 */ #if 0 if (bit_tskctxb(&(p_tcb->tskctxb))) { return(E_SYS_LINENO); } #endif } return(E_OK); }
/* * タスク毎の検査 */ static ER bit_mutex_task(ID tskid) { TCB *p_tcb; MTXCB *p_mtxcb; QUEUE *p_queue, *p_next; uint_t pri; if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) { return(E_ID); } p_tcb = get_tcb(tskid); pri = p_tcb->bpriority; /* * タスクがロックしているミューテックスのキューの検査 */ p_queue = p_tcb->mutex_queue.p_next; if (p_queue->p_prev != &(p_tcb->mutex_queue)) { return(E_SYS_LINENO); } while (p_queue != &(p_tcb->mutex_queue)) { p_mtxcb = MTXCB_QUEUE(p_queue); if (!VALID_MTXCB(p_mtxcb)) { return(E_SYS_LINENO); } /* * ミューテックスをロックしているタスクのチェック */ if (p_mtxcb->p_loctsk != p_tcb) { return(E_SYS_LINENO); } /* * 現在優先度の計算 */ if (MTXPROTO(p_mtxcb)) { if (p_mtxcb->p_mtxinib->ceilpri < pri) { pri = p_mtxcb->p_mtxinib->ceilpri; } } /* * キューの次の要素に進む */ p_next = p_queue->p_next; if (p_next->p_prev != p_queue) { return(E_SYS_LINENO); } p_queue = p_next; } /* * 現在優先度の検査 */ if (p_tcb->priority != pri) { return(E_SYS_LINENO); } /* * タスクが待っているミューテックスに関する検査 */ if (TSTAT_WAIT_MTX(p_tcb->tstat)) { p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb; if (!VALID_MTXCB(p_mtxcb)) { return(E_SYS_LINENO); } if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) { return(E_SYS_LINENO); } } return(E_OK); }