/* * タイムイベントヒープの先頭のノードの削除 */ 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; }
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); }
/* * 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; }
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); }
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(); }
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; }
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; }
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 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; }
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)); } }
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); }
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); }
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); }