Esempio n. 1
0
File: kos.c Progetto: puchinya/kos
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();
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}