Пример #1
0
kos_er_id_t kos_cre_dtq(const kos_cdtq_t *pk_cdtq)
{
	kos_dtq_cb_t *cb;
	int empty_index;
	kos_er_id_t er_id;
	
	kos_lock;
	
#ifdef KOS_CFG_ENA_ACRE_CONST_TIME_ID_SEARCH
	{
		kos_id_t last_id = g_kos_last_dtqid;

		if(last_id < g_kos_max_dtq) {
			empty_index = last_id;
			g_kos_last_dtqid = last_id + 1;
		} else {
			if(kos_list_empty(&g_kos_dtq_cb_unused_list)) {
				er_id = KOS_E_NOID;
				goto end;
			} else {
				kos_dtq_cb_t *unused_cb = (kos_dtq_cb_t *)g_kos_dtq_cb_unused_list.next;
				empty_index = CB_TO_INDEX(unused_cb);
				kos_list_remove((kos_list_t *)unused_cb);
			}
		}
	}
#else
	empty_index = kos_find_null((void **)g_kos_dtq_cb, g_kos_max_dtq);
	if(empty_index < 0) {
		er_id = KOS_E_NOID;
		goto end;
	}
#endif
	
	cb = &g_kos_dtq_cb_inst[empty_index];
	g_kos_dtq_cb[empty_index] = cb;
	
	cb->cdtq = *pk_cdtq;
	cb->dtq_rp = 0;
	cb->dtq_wp = 0;
	cb->sdtqcnt = 0;
	kos_list_init(&cb->r_wait_tsk_list);
	kos_list_init(&cb->s_wait_tsk_list);
	
	er_id = empty_index + 1;
end:
	kos_unlock;
	
	return er_id;
}
Пример #2
0
Файл: kos.c Проект: puchinya/kos
void kos_cancel_wait_nolock(kos_tcb_t *tcb, kos_er_t er)
{
	/* エラーコードを設定 */
	tcb->rel_wai_er = er;
	
	/* タイムアウトリストから解除 */
	if(tcb->st.lefttmo != KOS_TMO_FEVR) {
		kos_list_remove(&tcb->tmo_list);
		tcb->st.lefttmo = 0;	/* 必須ではない */
	}
	/* 待ちオブジェクトから削除 */
	if(tcb->st.wobjid != 0) {
		kos_list_remove(&tcb->wait_list);
		tcb->st.wobjid = 0;	/* 必須ではない */
	}
	
	tcb->st.tskwait = 0;	/* 必須ではない */
	
	if(tcb->st.tskstat == KOS_TTS_WAS) {
		tcb->st.tskstat = KOS_TTS_SUS;
	} else {
		kos_rdy_tsk_nolock(tcb);
	}
}
Пример #3
0
Файл: kos.c Проект: puchinya/kos
void kos_schedule_impl_nolock(void)
{
	uint32_t i, maxpri;
	kos_tcb_t *cur_tcb, *next_tcb;
	kos_list_t *rdy_que;
	
	KOS_SCHD_PORT_HI();

	/* 切り替え先タスクを探索する下限優先度を決定する */	
	cur_tcb = g_kos_cur_tcb;

	if(cur_tcb->st.tskstat == KOS_TTS_RUN) {
		/* 実行状態なら高い優先度のみを探索 */
		maxpri = cur_tcb->st.tskpri - 1;
	} else {
		/* 実行状態でなければ全優先度を探索 */
		maxpri = g_kos_max_pri;
	}
	
	/* 切り替え先タスクをRDYキューから探索 */
	next_tcb = KOS_NULL;
	rdy_que = g_kos_rdy_que;
	{
		kos_list_t *l = rdy_que;
		kos_list_t *l_end = &rdy_que[maxpri];
		while(l != l_end) {
			kos_list_t *l_next = l->next;
			if(l != l_next) {
				next_tcb = (kos_tcb_t *)l_next;
				break;
			}
			l++;
		}
	}
	
	/* 現在のタスクが実行中で切り替え先が無ければ何もしない。 */
	if(next_tcb == KOS_NULL) {
		KOS_SCHD_PORT_LO();
		return;
	}
	
#ifdef KOS_ARCH_CFG_SPT_PENDSV
	/* レディキューを編集するときは排他をかける */
	kos_ilock;
#endif

	if(cur_tcb->st.tskstat == KOS_TTS_RUN) {
		/* 現在のタスクが実行状態ならレディキューの先頭へ移動 */
		cur_tcb->st.tskstat = KOS_TTS_RDY;
		kos_list_insert_next(&rdy_que[cur_tcb->st.tskpri-1],
			(kos_list_t *)cur_tcb);
		
		kos_dbgprintf("tsk:%04X RDY\r\n", cur_tcb->id);
	}
	
	/* 切り替え先のタスクをレディキューから削除 */
	kos_list_remove((kos_list_t *)next_tcb);
	
#ifdef KOS_ARCH_CFG_SPT_PENDSV
	kos_iunlock;
#endif

	/* 切り替え先のタスクを実行状態へ変更 */
	next_tcb->st.tskstat = KOS_TTS_RUN;
	
	g_kos_cur_tcb = next_tcb;
	
	kos_dbgprintf("tsk:%04X RUN\r\n", next_tcb->id);

	KOS_SCHD_PORT_LO();
	
	/* コンテキストスイッチ */
	kos_arch_swi_sp(&cur_tcb->sp, next_tcb->sp);
}