static ER bit_semaphore(ID semid) { SEMCB *p_semcb; const SEMINIB *p_seminib; uint_t semcnt; QUEUE *p_queue; TCB *p_tcb; if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) { return(E_ID); } p_semcb = get_semcb(semid); p_seminib = p_semcb->p_seminib; semcnt = p_semcb->semcnt; /* * 初期化ブロックへのポインタの検査 */ if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) { return(E_SYS_LINENO); } /* * semcntの検査 */ if (semcnt > p_seminib->maxsem) { return(E_SYS_LINENO); } /* * wait_queueの検査 */ if (semcnt == 0) { p_queue = p_semcb->wait_queue.p_next; while (p_queue != &(p_semcb->wait_queue)) { p_tcb = (TCB *) p_queue; p_queue = p_queue->p_next; if (!VALID_TCB(p_tcb)) { return(E_SYS_LINENO); } if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) { return(E_SYS_LINENO); } if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) { return(E_SYS_LINENO); } } } else { if (!queue_empty(&(p_semcb->wait_queue))) { return(E_SYS_LINENO); } } return(E_OK); }
/* * ミューテックス毎の検査 */ 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); }