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; }
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); } }
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); }