示例#1
0
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);
}