Beispiel #1
0
uint_t
tmevt_up(TEVTCB *p_tevtcb, uint_t index, EVTTIM time)
{
	uint_t	parent;

	while (index > 1) {
		/*
		 *  親ノードのイベント発生時刻の方が早い(または同じ)
		 *  ならば,index が挿入位置なのでループを抜ける.
		 */
		parent = PARENT(index);
		if (EVTTIM_LE(p_tevtcb, TMEVT_NODE(p_tevtcb, parent).time, time)) {
			break;
		}

		/*
		 *  親ノードを index の位置に移動させる.
		 */
		TMEVT_NODE(p_tevtcb, index) = TMEVT_NODE(p_tevtcb, parent);
		TMEVT_NODE(p_tevtcb, index).p_tmevtb->index = index;

		/*
		 *  index を親ノードの位置に更新.
		 */
		index = parent;
	}
	return(index);
}
RELTIM
tmevt_lefttim(TMEVTB *p_tmevtb)
{
	EVTTIM	evttim, current_evttim_ub;

	/*
	 *  現在のイベント時刻を遅い方に丸めた時刻を求める[ASPD1050].
	 */
	update_current_evttim();
	current_evttim_ub = calc_current_evttim_ub();

	/*
	 *  タイムイベント発生までの相対時間を求める[ASPD1049].
	 */
	evttim = p_tmevtb->evttim;
	if (EVTTIM_LE(evttim, current_evttim_ub)) {
		/*
		 *  タイムイベントの発生時刻を過ぎている場合には0を返す[NGKI0552].
		 */
		return(0U);
	}
	else {
		return((RELTIM)(evttim - current_evttim_ub));
	}
}
uint_t
tmevt_up(uint_t index, EVTTIM time)
{
	uint_t	parent;

	while (index > 1) {
		/*
		 *  if 'time' is not earlier than parent's time.
		 *  break, the right position is found
		 */
		parent = PARENT(index);
		if (EVTTIM_LE(TMEVT_NODE(parent).time, time)) {
			break;
		}

		/*  else
		 *  move down the parent
		 */
		TMEVT_NODE(index) = TMEVT_NODE(parent);
		TMEVT_NODE(index).p_tmevtb->index = index;

		/*
		 *  update index
		 *  new loop begins
		 */
		index = parent;
	}
	return(index);
}
TMEVTN *
tmevt_up(TMEVTN *p_tmevtn, EVTTIM evttim)
{
	TMEVTN	*p_parent;

	while (p_tmevtn > p_top_tmevtn) {
		/*
		 *  親ノードのイベント発生時刻の方が早い(または同じ)ならば,
		 *  p_tmevtnが挿入位置なのでループを抜ける.
		 */
		p_parent = PARENT(p_tmevtn);
		if (EVTTIM_LE(p_parent->p_tmevtb->evttim, evttim)) {
			break;
		}

		/*
		 *  親ノードをp_tmevtnの位置に移動させる.
		 */
		*p_tmevtn = *p_parent;
		p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;

		/*
		 *  p_tmevtnを親ノードの位置に更新.
		 */
		p_tmevtn = p_parent;
	}
	return(p_tmevtn);
}
Beispiel #5
0
void
signal_time(void)
{
	TMEVTB	*p_tmevtb;
	PCB		*my_p_pcb;
	TEVTCB	*my_p_tevtcb;

	assert(sense_context());
	assert(!i_sense_lock());

	i_lock_cpu();
	my_p_pcb = i_acquire_tsk_lock_self();

	my_p_tevtcb = my_p_pcb->p_tevtcb;

	/*
	 *  current_timeを更新する.
	 */
	my_p_tevtcb->current_time = my_p_tevtcb->next_time;

	/*
	 *  next_time,next_subtimeを更新する.
	 */
#if TIC_DENO == 1U
	my_p_tevtcb->next_time = my_p_tevtcb->current_time + TIC_NUME;
#else /* TIC_DENO == 1U */
	my_p_tevtcb->next_subtime += TIC_NUME % TIC_DENO;
	my_p_tevtcb->next_time = my_p_tevtcb->current_time + TIC_NUME / TIC_DENO;
	if (my_p_tevtcb->next_subtime >= TIC_DENO) {
		my_p_tevtcb->next_subtime -= TIC_DENO;
		my_p_tevtcb->next_time += 1U;
	}
#endif /* TIC_DENO == 1U */

	/*
	 *  curent_timeよりイベント発生時刻の早い(または同じ)タイムイベン
	 *  トを,タイムイベントヒープから削除し,コールバック関数を呼び出
	 *  す.
	 */
	while ((my_p_tevtcb->last_index) > 0 && EVTTIM_LE(my_p_tevtcb, TMEVT_NODE(my_p_tevtcb, 1).time, my_p_tevtcb->current_time)) {
		p_tmevtb = TMEVT_NODE(my_p_tevtcb, 1).p_tmevtb;
		tmevtb_delete_top(my_p_tevtcb);
		(*(p_tmevtb->callback))(p_tmevtb->arg);
	}

	/*
	 *  min_timeを更新する.
	 */
	my_p_tevtcb->min_time = my_p_tevtcb->current_time;

	release_tsk_lock(my_p_pcb);
	i_unlock_cpu();
}
bool_t
check_adjtim(int_t adjtim)
{
	if (adjtim > 0) {
		return(p_last_tmevtn >= p_top_tmevtn	/*[NGKI3588]*/
					&& EVTTIM_LE(top_evttim, current_evttim - TMAX_ADJTIM));
	}
	else if (adjtim < 0) {						/*[NGKI3589]*/
		return(monotonic_evttim - current_evttim >= -TMIN_ADJTIM);
	}
	return(false);
}
Beispiel #7
0
RELTIM
tmevt_lefttim(TEVTCB *p_tevtcb, TMEVTB *p_tmevtb)
{
	EVTTIM	time;

	time = TMEVT_NODE(p_tevtcb, p_tmevtb->index).time;
	if (EVTTIM_LE(p_tevtcb, time, p_tevtcb->next_time)) {
		/*
		 *  次のタイムティックで処理される場合には0を返す.
		 */
		return(0U);
	}
	else {
		return((RELTIM)(time - base_time(p_tevtcb)));
	}
}
RELTIM
tmevt_lefttim(TMEVTB *p_tmevtb)
{
	EVTTIM	time;

	time = TMEVT_NODE(p_tmevtb->index).time;
	if (EVTTIM_LE(time, next_time)) {
		/*
		 *  if earlier than next system time
		 */
		return(0U);
	}
	else {
		return((RELTIM)(time - base_time));
	}
}
Beispiel #9
0
void
time_event_enqueue(ID tmevtid , EVTTIM evttim , CBACK callback , uintptr_t arg)
{
	QUEIDX pos = TMEVT_HEAD().next;
	
	/* 挿入位置を検索 */
	while((pos != TMEVT_NULL)
			&& (EVTTIM_LE(tmevt_time[pos] , evttim))) {
		pos = tmevt_queue[pos].next;
	}
	
	/* キューに挿入 */
	queue_insert_prev(&(tmevt_queue[0]) , pos , (QUEIDX)tmevtid);
	tmevt_callback[tmevtid] = (CBACK)callback;
	tmevt_arg[tmevtid] = arg;
	tmevt_time[tmevtid] = evttim;
}
Beispiel #10
0
void
signal_time(void)
{
	TMEVTB	*p_tmevtb;

	assert(sense_context());
	assert(!i_sense_lock());

	i_lock_cpu();

	/*
	 *  update current time
	 */
	current_time = next_time;

	/*
	 *  update next_time and next_sub time
	 */
#if TIC_DENO == 1U
	next_time = current_time + TIC_NUME;
#else /* TIC_DENO == 1U */
	next_subtime += TIC_NUME % TIC_DENO;
	next_time = current_time + TIC_NUME / TIC_DENO;
	if (next_subtime >= TIC_DENO) {
		next_subtime -= TIC_DENO;
		next_time += 1U;
	}
#endif /* TIC_DENO == 1U */

	/*
	 *  if current time is not earlier than the earliest time event in time
	 *  event heap, it means a time event shall happen
	 */
	while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, current_time)) {
		p_tmevtb = TMEVT_NODE(1).p_tmevtb;
		tmevtb_delete_top();
		(*(p_tmevtb->callback))(p_tmevtb->arg);
	}

	/*
	 *  update min time
	 */
	min_time = current_time;

	i_unlock_cpu();
}
void
signal_time(void)
{
	TMEVTB	*p_tmevtb;
	bool_t	callflag;

	assert(sense_context());
	assert(!sense_lock());

	lock_cpu();
	in_signal_time = true;							/*[ASPD1033]*/

	do {
		/*
		 *  コールバック関数を呼び出さなければループを抜ける[ASPD1020].
		 */
		callflag = false;

		/*
		 *  現在のイベント時刻を求める[ASPD1022].
		 */
		update_current_evttim();

		/*
		 *  発生時刻がcurrent_evttim以前のタイムイベントがあれば,タイ
		 *  ムイベントヒープから削除し,コールバック関数を呼び出す
		 *  [ASPD1018][ASPD1019].
		 */
		while (p_last_tmevtn >= p_top_tmevtn
							&& EVTTIM_LE(top_evttim, current_evttim)) {
			p_tmevtb = tmevtb_delete_top();
			(*(p_tmevtb->callback))(p_tmevtb->arg);
			callflag = true;
		}
	} while (callflag);								/*[ASPD1020]*/

	/*
	 *  高分解能タイマ割込みの発生タイミングを設定する[ASPD1025].
	 */
	set_hrt_event();

	in_signal_time = false;							/*[ASPD1033]*/
	unlock_cpu();
}
void
set_hrt_event(void)
{
	HRTCNT	hrtcnt;

	if (p_last_tmevtn < p_top_tmevtn) {
		target_hrt_set_event(HRTCNT_BOUND);			/*[ASPD1007]*/
	}
	else if (EVTTIM_LE(top_evttim, current_evttim)) {
		target_hrt_raise_event();					/*[ASPD1017]*/
	}
	else {
		hrtcnt = (HRTCNT)(top_evttim - current_evttim);
		if (hrtcnt > HRTCNT_BOUND) {
			target_hrt_set_event(HRTCNT_BOUND);		/*[ASPD1006]*/
		}
		else {
			target_hrt_set_event(hrtcnt);			/*[ASPD1002]*/
		}
	}
}
Beispiel #13
0
uint_t
tmevt_down(TEVTCB *p_tevtcb, uint_t index, EVTTIM time)
{
	uint_t	child;

	while ((child = LCHILD(index)) <= p_tevtcb->last_index) {
		/*
		 *  左右の子ノードのイベント発生時刻を比較し,早い方の
		 *  子ノードの位置を child に設定する.以下の子ノード
		 *  は,ここで選ばれた方の子ノードのこと.
		 */
		if (child + 1 <= p_tevtcb->last_index
						&& EVTTIM_LT(p_tevtcb,
									 TMEVT_NODE(p_tevtcb, child + 1).time,
									 TMEVT_NODE(p_tevtcb, child).time)) {
			child = child + 1;
		}

		/*
		 *  子ノードのイベント発生時刻の方が遅い(または同じ)
		 *  ならば,index が挿入位置なのでループを抜ける.
		 */
		if (EVTTIM_LE(p_tevtcb, time, TMEVT_NODE(p_tevtcb, child).time)) {
			break;
		}

		/*
		 *  子ノードを index の位置に移動させる.
		 */
		TMEVT_NODE(p_tevtcb, index) = TMEVT_NODE(p_tevtcb, child);
		TMEVT_NODE(p_tevtcb, index).p_tmevtb->index = index;

		/*
		 *  index を子ノードの位置に更新.
		 */
		index = child;
	}
	return(index);
}
Beispiel #14
0
uint_t
tmevt_down(uint_t index, EVTTIM time)
{
	uint_t	child;

	while ((child = LCHILD(index)) <= last_index) {
		/*
		 *  use to the earlier child in two children(left, right),
		 *  to compare with 'time'
		 * 
		 */
		if (child + 1 <= last_index
						&& EVTTIM_LT(TMEVT_NODE(child + 1).time,
										TMEVT_NODE(child).time)) {
			child = child + 1;
		}

		/*
		 *  if the selected child is not earlier than 'time',
		 *  the right position if found
		 */
		if (EVTTIM_LE(time, TMEVT_NODE(child).time)) {
			break;
		}

		/*
		 *  move up the selected child
		 */
		TMEVT_NODE(index) = TMEVT_NODE(child);
		TMEVT_NODE(index).p_tmevtb->index = index;

		/*
		 *  update index
		 *  new loop begins
		 */
		index = child;
	}
	return(index);
}
TMEVTN *
tmevt_down(TMEVTN *p_tmevtn, EVTTIM evttim)
{
	TMEVTN	*p_child;

	while ((p_child = LCHILD(p_tmevtn)) <= p_last_tmevtn) {
		/*
		 *  左右の子ノードのイベント発生時刻を比較し,早い方の子ノード
		 *  の位置をp_childに設定する.以下の子ノードは,ここで選ばれた
		 *  方の子ノードのこと.
		 */
		if (p_child + 1 <= p_last_tmevtn
					&& EVTTIM_LT((p_child + 1)->p_tmevtb->evttim,
											p_child->p_tmevtb->evttim)) {
			p_child = p_child + 1;
		}

		/*
		 *  子ノードのイベント発生時刻の方が遅い(または同じ)ならば,
		 *  p_tmevtnが挿入位置なのでループを抜ける.
		 */
		if (EVTTIM_LE(evttim, p_child->p_tmevtb->evttim)) {
			break;
		}

		/*
		 *  子ノードをp_tmevtnの位置に移動させる.
		 */
		*p_tmevtn = *p_child;
		p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;

		/*
		 *  p_tmevtnを子ノードの位置に更新.
		 */
		p_tmevtn = p_child;
	}
	return(p_tmevtn);
}