void kos_rdy_tsk_nolock(kos_tcb_t *tcb) { /* RDY状態に変更 */ tcb->st.tskstat = KOS_TTS_RDY; /* RDYキューへ追加 */ kos_list_insert_prev(&g_kos_rdy_que[tcb->st.tskpri-1], (kos_list_t *)tcb); kos_dbgprintf("tsk:%04X RDY\r\n", tcb->id); }
void kos_wait_nolock(kos_tcb_t *tcb) { /* ディスパッチ禁止状態で呼ばれた場合はエラーを返す */ if(g_kos_dsp) { tcb->rel_wai_er = KOS_E_CTX; return; } /* 無限待ちでなければタイムアウトリストにもつなげる */ if(tcb->st.lefttmo != KOS_TMO_FEVR) { kos_list_insert_prev(&g_kos_tmo_wait_list, &tcb->tmo_list); } kos_dbgprintf("tsk:%04X WAI\r\n", tcb->id); /* WAI状態へ変更 */ tcb->st.tskstat = KOS_TTS_WAI; kos_force_tsk_dsp(); }
kos_er_t kos_del_dtq(kos_id_t dtqid) { kos_dtq_cb_t *cb; kos_er_t er; kos_bool_t do_tsk_dsp; #ifdef KOS_CFG_ENA_PAR_CHK if(dtqid > g_kos_max_dtq || dtqid == 0) return KOS_E_ID; #endif er = KOS_E_OK; kos_lock; cb = kos_get_dtq_cb(dtqid); if(cb == KOS_NULL) { er = KOS_E_NOEXS; goto end; } /* 待ち行列にいるタスクの待ちを解除 */ do_tsk_dsp = kos_cancel_wait_all_for_delapi_nolock(&cb->r_wait_tsk_list); do_tsk_dsp |= kos_cancel_wait_all_for_delapi_nolock(&cb->s_wait_tsk_list); /* 登録解除 */ g_kos_dtq_cb[dtqid - 1] = KOS_NULL; #ifdef KOS_CFG_ENA_ACRE_CONST_TIME_ID_SEARCH kos_list_insert_prev(&g_kos_dtq_cb_unused_list, (kos_list_t *)cb); #endif /* スケジューラー起動 */ if(do_tsk_dsp) { kos_tsk_dsp(); } end: kos_unlock; return er; }
kos_er_t kos_trcv_dtq(kos_id_t dtqid, kos_vp_int_t *p_data, kos_tmo_t tmout) { kos_dtq_cb_t *cb; kos_er_t er; #ifdef KOS_CFG_ENA_PAR_CHK if(dtqid > g_kos_max_dtq || dtqid == 0) return KOS_E_ID; if(p_data == KOS_NULL) return KOS_E_PAR; #endif er = KOS_E_OK; kos_lock; cb = kos_get_dtq_cb(dtqid); if(cb == KOS_NULL) { er = KOS_E_NOEXS; goto end_unlock; } if(cb->sdtqcnt > 0) { /* キューにデータがあれば取り出す */ kos_uint_t rp; rp = cb->dtq_rp; *p_data = ((kos_vp_int_t *)cb->cdtq.dtq)[rp]; rp++; if(rp >= cb->cdtq.dtqcnt) rp = 0; cb->dtq_rp = rp; cb->sdtqcnt--; /* 送信待ちのタスクが入れば送信データをキューの末尾に追加して待ちを解除 */ if(!kos_list_empty(&cb->s_wait_tsk_list)) { kos_tcb_t *tcb; tcb = (kos_tcb_t *)cb->s_wait_tsk_list.next; ((kos_vp_int_t *)cb->cdtq.dtq)[cb->dtq_wp++] = (kos_vp_int_t)tcb->wait_exinf; cb->sdtqcnt++; kos_cancel_wait_nolock(tcb, KOS_E_OK); kos_tsk_dsp(); } } else { if(!kos_list_empty(&cb->s_wait_tsk_list)) { /* データ送信待ちのタスクが入ればデータを取得して待ちを解除 */ kos_tcb_t *tcb; tcb = (kos_tcb_t *)cb->s_wait_tsk_list.next; *p_data = (kos_vp_int_t)tcb->wait_exinf; kos_cancel_wait_nolock(tcb, KOS_E_OK); kos_tsk_dsp(); } else if(tmout == KOS_TMO_POL) { er = KOS_E_TMOUT; goto end_unlock; } else { /* データが送信されるまで待つ */ kos_tcb_t *tcb = g_kos_cur_tcb; kos_list_insert_prev(&cb->r_wait_tsk_list, &tcb->wait_list); tcb->st.lefttmo = tmout; tcb->st.wobjid = dtqid; tcb->st.tskwait = KOS_TTW_RDTQ; tcb->wait_exinf = (kos_vp_t)p_data; kos_wait_nolock(tcb); kos_unlock; er = tcb->rel_wai_er; goto end; } } end_unlock: kos_unlock; end: return er; }
kos_er_t kos_tsnd_dtq(kos_id_t dtqid, kos_vp_int_t data, kos_tmo_t tmout) { kos_dtq_cb_t *cb; kos_er_t er; #ifdef KOS_CFG_ENA_PAR_CHK if(dtqid > g_kos_max_dtq || dtqid == 0) return KOS_E_ID; #endif er = KOS_E_OK; kos_lock; cb = kos_get_dtq_cb(dtqid); if(cb == KOS_NULL) { er = KOS_E_NOEXS; goto end_unlock; } if(!kos_list_empty(&cb->r_wait_tsk_list)) { /* 受信待ちのタスクがいればデータを渡して終わり */ kos_tcb_t *tcb; tcb = (kos_tcb_t *)cb->r_wait_tsk_list.next; *((kos_vp_int_t *)tcb->wait_exinf) = data; kos_cancel_wait_nolock(tcb, KOS_E_OK); kos_tsk_dsp(); } else { if(cb->sdtqcnt == cb->cdtq.dtqcnt) { /* 空きがない場合 */ if(tmout == KOS_TMO_POL) { er = KOS_E_TMOUT; goto end_unlock; } else { kos_tcb_t *tcb = g_kos_cur_tcb; kos_list_insert_prev(&cb->s_wait_tsk_list, &tcb->wait_list); tcb->st.lefttmo = tmout; tcb->st.wobjid = dtqid; tcb->st.tskwait = KOS_TTW_SDTQ; tcb->wait_exinf = (kos_vp_t)data; kos_wait_nolock(tcb); kos_unlock; er = tcb->rel_wai_er; goto end; } } else { /* 空きがあればキューにデータを追加 */ kos_uint_t wp; wp = cb->dtq_wp; ((kos_vp_int_t *)cb->cdtq.dtq)[wp] = data; wp++; if(wp >= cb->cdtq.dtqcnt) wp = 0; cb->dtq_wp = wp; cb->sdtqcnt++; if(!kos_list_empty(&cb->r_wait_tsk_list)) { kos_tcb_t *tcb = (kos_tcb_t *)cb->r_wait_tsk_list.next; kos_cancel_wait_nolock(tcb, KOS_E_OK); kos_tsk_dsp(); } } } end_unlock: kos_unlock; end: return er; }