void kos_process_tmo(void) { kos_bool_t do_dsp; kos_list_t *l, *end, *next; do_dsp = KOS_FALSE; end = &g_kos_tmo_wait_list; for(l = end->next; l != end; ) { kos_tcb_t *tcb; next = l->next; tcb = (kos_tcb_t *)((uint8_t *)l - offsetof(kos_tcb_t, tmo_list)); if(--tcb->st.lefttmo == 0) { /* 割り込みをマスクして待ち解除を行う */ kos_ilock; kos_cancel_wait_nolock(tcb, KOS_E_TMOUT); kos_iunlock; do_dsp = KOS_TRUE; } l = next; } /* 1つ以上の待ちを解除したらディスパッチを行う */ if(do_dsp) { kos_itsk_dsp(); } }
kos_er_t kos_ipsnd_dtq(kos_id_t dtqid, kos_vp_int_t data) { 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_ilock; cb = kos_get_dtq_cb(dtqid); if(cb == KOS_NULL) { er = KOS_E_NOEXS; goto end; } 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_itsk_dsp(); } else { if(cb->sdtqcnt == cb->cdtq.dtqcnt) { /* 空きがない場合 */ er = KOS_E_TMOUT; 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_itsk_dsp(); } } } end: kos_iunlock; 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; }