Exemplo n.º 1
0
/*
 *  タイムイベントヒープの先頭のノードの削除
 */
Inline void
tmevtb_delete_top(TEVTCB* p_tevtcb)
{
	uint_t	index;
	EVTTIM	event_time = TMEVT_NODE(p_tevtcb, p_tevtcb->last_index).time;

	/*
	 *  削除によりタイムイベントヒープが空になる場合は何もしない.
	 */
	if (--(p_tevtcb->last_index) == 0) {
		return;
	}

	/*
	 *  ルートノードに最後のノード(last_index + 1 の位置のノード)を
	 *  挿入し,それを適切な位置へ移動させる.実際には,最後のノードを
	 *  実際に挿入するのではなく,ルートノードが空ノードになるので,最
	 *  後のノードを挿入すべき位置へ向けて空ノードを移動させる.
	 */
	index = tmevt_down(p_tevtcb, 1, event_time);

	/*
	 *  最後のノードをindexの位置に挿入する.
	 */ 
	TMEVT_NODE(p_tevtcb, index) = TMEVT_NODE(p_tevtcb, p_tevtcb->last_index + 1);
	TMEVT_NODE(p_tevtcb, index).p_tmevtb->index = index;
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
/*
 *  delete the top time event in time event heap
 */
Inline void
tmevtb_delete_top(void)
{
	uint_t	index;
	EVTTIM	event_time = TMEVT_NODE(last_index).time;

	/*
	 *  last_index--
	 *  if last_index == 0
	 *  do nothing.
	 */
	if (--last_index == 0) {
		return;
	}

	/*
	 *  search down to find righ position for last time event
	 *  in heap
	 */
	index = tmevt_down(1, event_time);

	/*
	 *  update info.
	 */ 
	TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
	TMEVT_NODE(index).p_tmevtb->index = index;
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 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();
}
Exemplo n.º 6
0
void
tmevtb_delete(TMEVTB *p_tmevtb)
{
	uint_t	index = p_tmevtb->index;
	uint_t	parent;
	EVTTIM	event_time = TMEVT_NODE(last_index).time;

	/*
	 *  last_index--
	 *  if last_index == 0
	 *  do nothing.
	 */
	if (--last_index == 0) {
		return;
	}

	/*
	 *
	 *  insert the last time event into the position of deleted time
	 *  event. In fact, the insert does not happened. The position of 
	 *  deleted time will be a empty node in time event heap. Then this
	 *  empty node will be moved to a right position which is the right
	 *  position of the last time event. 
	 * 
	 *  If the event time of the last time event is earlier than deleted
	 *  time event's parent, then search up, or search down.
	 *
	 */
	if (index > 1 && EVTTIM_LT(event_time,
								TMEVT_NODE(parent = PARENT(index)).time)) {
		/*
		 *  if deleted time event's parent is not earlier than last time event
		 *  in heap, change parent's position and update info.
		 * 
		 */
		TMEVT_NODE(index) = TMEVT_NODE(parent);
		TMEVT_NODE(index).p_tmevtb->index = index;

		/*
		 *  then search up to find the right position for the last time event in heap
		 *  from parent's position
		 */
		index = tmevt_up(parent, event_time);
	}
	else {
		/*
		 *  search down to find right position for last time event in heap.
		 */
		index = tmevt_down(index, event_time);
	}

	/*
	 * update the last time event's info
	 */ 
	TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
	TMEVT_NODE(index).p_tmevtb->index = index;
}
Exemplo n.º 7
0
void
tmevtb_insert(TEVTCB *p_tevtcb, TMEVTB *p_tmevtb, EVTTIM time)
{
	uint_t	index;

	/*
	 *  last_index をインクリメントし,そこから上に挿入位置を探す.
	 */
	index = tmevt_up(p_tevtcb, ++(p_tevtcb->last_index), time);

	/*
	 *  タイムイベントを index の位置に挿入する.
	 */ 
	TMEVT_NODE(p_tevtcb, index).time = time;
	TMEVT_NODE(p_tevtcb, index).p_tmevtb = p_tmevtb;
	p_tmevtb->index = index;
}
Exemplo n.º 8
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();
}
Exemplo n.º 9
0
void
tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time)
{
	uint_t	index;

	/*
	 *  last_index++
	 *  search up.
	 *  index is the right position for this
	 *  time event
	 */
	index = tmevt_up(++last_index, time);

	/*
	 *  insert time event in the right position 
	 */ 
	TMEVT_NODE(index).time = time;
	TMEVT_NODE(index).p_tmevtb = p_tmevtb;
	p_tmevtb->index = index;
}
Exemplo n.º 10
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)));
	}
}
Exemplo n.º 11
0
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));
	}
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
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);
}
Exemplo n.º 14
0
RELTIM
tmevtb_delete(TEVTCB *p_tevtcb, TMEVTB *p_tmevtb)
{
	uint_t	index = p_tmevtb->index;
	uint_t	parent;
	EVTTIM	event_time = TMEVT_NODE(p_tevtcb, p_tevtcb->last_index).time;
	EVTTIM	time;
	RELTIM	left_time;

	/*
	 *  タイムイベントまでの残り時間を計算
	 *  tmevt_leftim()とは異なり大きい方(current_timeとの差分)に丸める. 
	 */
	time = TMEVT_NODE(p_tevtcb, p_tmevtb->index).time;
	left_time = (RELTIM)(time - p_tevtcb->current_time);

	/*
	 *  削除によりタイムイベントヒープが空になる場合は何もしない.
	 */
	if (--(p_tevtcb->last_index) == 0) {
		return(left_time);
	}

	/*
	 *  削除したノードの位置に最後のノード(last_index+1の位置のノード)
	 *  を挿入し,それを適切な位置へ移動させる.実際には,最後のノード
	 *  を実際に挿入するのではなく,削除したノードの位置が空ノードにな
	 *  るので,最後のノードを挿入すべき位置へ向けて空ノードを移動させ
	 *  る.
	 *  最後のノードのイベント発生時刻が,削除したノードの親ノードのイ
	 *  ベント発生時刻より前の場合には,上に向かって挿入位置を探す.そ
	 *  うでない場合には,下に向かって探す.
	 */
	if (index > 1 && EVTTIM_LT(p_tevtcb, event_time,
								TMEVT_NODE(p_tevtcb, parent = PARENT(index)).time)) {
		/*
		 *  親ノードをindexの位置に移動させる.
		 */
		TMEVT_NODE(p_tevtcb, index) = TMEVT_NODE(p_tevtcb, parent);
		TMEVT_NODE(p_tevtcb, index).p_tmevtb->index = index;

		/*
		 *  削除したノードの親ノードから上に向かって挿入位置を探す.
		 */
		index = tmevt_up(p_tevtcb, parent, event_time);
	}
	else {
		/*
		 *  削除したノードから下に向かって挿入位置を探す.
		 */
		index = tmevt_down(p_tevtcb, index, event_time);
	}

	/*
	 *  最後のノードをindexの位置に挿入する.
	 */ 
	TMEVT_NODE(p_tevtcb, index) = TMEVT_NODE(p_tevtcb, (p_tevtcb->last_index) + 1);
	TMEVT_NODE(p_tevtcb, index).p_tmevtb->index = index;

	return(left_time);
}