time_event.c

#include "kernel_impl.h"
#include "check.h"
#include "time_event.h"

ソースコードを見る。

マクロ定義

#define PARENT(index)   ((index) >> 1)
#define LCHILD(index)   ((index) << 1)
#define TMEVT_NODE(index)   (tmevt_heap[(index) - 1])
#define EVTTIM_LT(t1, t2)   (((t1) - current_time) < ((t2) - current_time))
#define EVTTIM_LE(t1, t2)   (((t1) - current_time) <= ((t2) - current_time))

関数

void initialize_tmevt (void)
uint_t tmevt_up (uint_t index, EVTTIM time)
uint_t tmevt_down (uint_t index, EVTTIM time)
void tmevtb_insert (TMEVTB *p_tmevtb, EVTTIM time)
void tmevtb_delete (TMEVTB *p_tmevtb)
Inline void tmevtb_delete_top (void)
RELTIM tmevt_lefttim (TMEVTB *p_tmevtb)
void signal_time (void)

変数

EVTTIM current_time
EVTTIM next_time
uint_t next_subtime
uint_t last_index


マクロ定義

#define EVTTIM_LE ( t1,
t2   )     (((t1) - current_time) <= ((t2) - current_time))

time_event.c66 行で定義されています。

参照元 signal_time(), tmevt_down(), tmevt_lefttim(), と tmevt_up().

#define EVTTIM_LT ( t1,
t2   )     (((t1) - current_time) < ((t2) - current_time))

time_event.c65 行で定義されています。

参照元 tmevt_down(), と tmevtb_delete().

#define LCHILD ( index   )     ((index) << 1)

time_event.c55 行で定義されています。

参照元 tmevt_down().

#define PARENT ( index   )     ((index) >> 1)

time_event.c54 行で定義されています。

参照元 tmevt_up(), と tmevtb_delete().

#define TMEVT_NODE ( index   )     (tmevt_heap[(index) - 1])


関数

void initialize_tmevt ( void   ) 

time_event.c98 行で定義されています。

参照先 current_time, last_index, next_subtime, next_time, TIC_DENO, と TIC_NUME.

00099 {
00100     current_time = 0U;
00101     next_time = current_time + TIC_NUME / TIC_DENO;
00102 #if TIC_DENO != 1U
00103     next_subtime = TIC_NUME % TIC_DENO;
00104 #endif /* TIC_DENO != 1U */
00105     last_index = 0U;
00106 }

void signal_time ( void   ) 

time_event.c347 行で定義されています。

参照先 time_event_block::arg, assert, time_event_block::callback, current_time, EVTTIM_LE, i_lock_cpu, i_sense_lock, i_unlock_cpu, last_index, next_subtime, next_time, sense_context(), TIC_DENO, TIC_NUME, TMEVT_NODE, と tmevtb_delete_top().

00348 {
00349     TMEVTB  *p_tmevtb;
00350 
00351     assert(sense_context());
00352     assert(!i_sense_lock());
00353     i_lock_cpu();
00354 
00355     /*
00356      *  next_timeよりイベント発生時刻の早い(または同じ)タイムイベン
00357      *  トを,タイムイベントヒープから削除し,コールバック関数を呼び出
00358      *  す.
00359      */
00360     while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, next_time)) {
00361         p_tmevtb = TMEVT_NODE(1).p_tmevtb;
00362         tmevtb_delete_top();
00363         (*(p_tmevtb->callback))(p_tmevtb->arg);
00364     }
00365 
00366     /*
00367      *  current_timeを更新する.
00368      */
00369     current_time = next_time;
00370 
00371     /*
00372      *  next_time,next_subtimeを更新する.
00373      *
00374      *  TIC_NUME < TIC_DENOの時は,除算を使わずに時刻の更新ができるが,
00375      *  ソースコードを読みやすくにするために#ifの多用を避けている.
00376      */
00377 #if TIC_DENO == 1U
00378     next_time = current_time + TIC_NUME;
00379 #else /* TIC_DENO == 1U */
00380     next_subtime += TIC_NUME % TIC_DENO;
00381     next_time = current_time + TIC_NUME / TIC_DENO;
00382     if (next_subtime >= TIC_DENO) {
00383         next_subtime -= TIC_DENO;
00384         next_time += 1U;
00385     }
00386 #endif /* TIC_DENO == 1U */
00387 
00388     i_unlock_cpu();
00389 }

uint_t tmevt_down ( uint_t  index,
EVTTIM  time 
)

time_event.c160 行で定義されています。

参照先 EVTTIM_LE, EVTTIM_LT, last_index, LCHILD, と TMEVT_NODE.

00161 {
00162     uint_t  child;
00163 
00164     while ((child = LCHILD(index)) <= last_index) {
00165         /*
00166          *  左右の子ノードのイベント発生時刻を比較し,早い方の
00167          *  子ノードの位置を child に設定する.以下の子ノード
00168          *  は,ここで選ばれた方の子ノードのこと.
00169          */
00170         if (child + 1 <= last_index
00171                         && EVTTIM_LT(TMEVT_NODE(child + 1).time,
00172                                         TMEVT_NODE(child).time)) {
00173             child = child + 1;
00174         }
00175 
00176         /*
00177          *  子ノードのイベント発生時刻の方が遅い(または同じ)
00178          *  ならば,index が挿入位置なのでループを抜ける.
00179          */
00180         if (EVTTIM_LE(time, TMEVT_NODE(child).time)) {
00181             break;
00182         }
00183 
00184         /*
00185          *  子ノードを index の位置に移動させる.
00186          */
00187         TMEVT_NODE(index) = TMEVT_NODE(child);
00188         TMEVT_NODE(index).p_tmevtb->index = index;
00189 
00190         /*
00191          *  index を子ノードの位置に更新.
00192          */
00193         index = child;
00194     }
00195     return(index);
00196 }

RELTIM tmevt_lefttim ( TMEVTB p_tmevtb  ) 

time_event.c323 行で定義されています。

参照先 base_time, EVTTIM_LE, time_event_block::index, next_time, と TMEVT_NODE.

00324 {
00325     EVTTIM  time;
00326 
00327     time = TMEVT_NODE(p_tmevtb->index).time;
00328     if (EVTTIM_LE(time, next_time)) {
00329         /*
00330          *  次のタイムティックで処理される場合には0を返す.
00331          */
00332         return(0U);
00333     }
00334     else {
00335         return((RELTIM)(time - base_time));
00336     }
00337 }

uint_t tmevt_up ( uint_t  index,
EVTTIM  time 
)

time_event.c120 行で定義されています。

参照先 EVTTIM_LE, PARENT, と TMEVT_NODE.

00121 {
00122     uint_t  parent;
00123 
00124     while (index > 1) {
00125         /*
00126          *  親ノードのイベント発生時刻の方が早い(または同じ)
00127          *  ならば,index が挿入位置なのでループを抜ける.
00128          */
00129         parent = PARENT(index);
00130         if (EVTTIM_LE(TMEVT_NODE(parent).time, time)) {
00131             break;
00132         }
00133 
00134         /*
00135          *  親ノードを index の位置に移動させる.
00136          */
00137         TMEVT_NODE(index) = TMEVT_NODE(parent);
00138         TMEVT_NODE(index).p_tmevtb->index = index;
00139 
00140         /*
00141          *  index を親ノードの位置に更新.
00142          */
00143         index = parent;
00144     }
00145     return(index);
00146 }

void tmevtb_delete ( TMEVTB p_tmevtb  ) 

time_event.c234 行で定義されています。

参照先 EVTTIM_LT, time_event_block::index, last_index, PARENT, tmevt_down, TMEVT_NODE, と tmevt_up.

00235 {
00236     uint_t  index = p_tmevtb->index;
00237     uint_t  parent;
00238     EVTTIM  event_time = TMEVT_NODE(last_index).time;
00239 
00240     /*
00241      *  削除によりタイムイベントヒープが空になる場合は何もしない.
00242      */
00243     if (--last_index == 0) {
00244         return;
00245     }
00246 
00247     /*
00248      *  削除したノードの位置に最後のノード(last_index+1の位置のノード)
00249      *  を挿入し,それを適切な位置へ移動させる.実際には,最後のノード
00250      *  を実際に挿入するのではなく,削除したノードの位置が空ノードにな
00251      *  るので,最後のノードを挿入すべき位置へ向けて空ノードを移動させ
00252      *  る.
00253      *  最後のノードのイベント発生時刻が,削除したノードの親ノードのイ
00254      *  ベント発生時刻より前の場合には,上に向かって挿入位置を探す.そ
00255      *  うでない場合には,下に向かって探す.
00256      */
00257     if (index > 1 && EVTTIM_LT(event_time,
00258                                 TMEVT_NODE(parent = PARENT(index)).time)) {
00259         /*
00260          *  親ノードをindexの位置に移動させる.
00261          */
00262         TMEVT_NODE(index) = TMEVT_NODE(parent);
00263         TMEVT_NODE(index).p_tmevtb->index = index;
00264 
00265         /*
00266          *  削除したノードの親ノードから上に向かって挿入位置を探す.
00267          */
00268         index = tmevt_up(parent, event_time);
00269     }
00270     else {
00271         /*
00272          *  削除したノードから下に向かって挿入位置を探す.
00273          */
00274         index = tmevt_down(index, event_time);
00275     }
00276 
00277     /*
00278      *  最後のノードをindexの位置に挿入する.
00279      */ 
00280     TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
00281     TMEVT_NODE(index).p_tmevtb->index = index;
00282 }

Inline void tmevtb_delete_top ( void   ) 

time_event.c290 行で定義されています。

参照先 last_index, tmevt_down, と TMEVT_NODE.

参照元 signal_time().

00291 {
00292     uint_t  index;
00293     EVTTIM  event_time = TMEVT_NODE(last_index).time;
00294 
00295     /*
00296      *  削除によりタイムイベントヒープが空になる場合は何もしない.
00297      */
00298     if (--last_index == 0) {
00299         return;
00300     }
00301 
00302     /*
00303      *  ルートノードに最後のノード(last_index + 1 の位置のノード)を
00304      *  挿入し,それを適切な位置へ移動させる.実際には,最後のノードを
00305      *  実際に挿入するのではなく,ルートノードが空ノードになるので,最
00306      *  後のノードを挿入すべき位置へ向けて空ノードを移動させる.
00307      */
00308     index = tmevt_down(1, event_time);
00309 
00310     /*
00311      *  最後のノードをindexの位置に挿入する.
00312      */ 
00313     TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
00314     TMEVT_NODE(index).p_tmevtb->index = index;
00315 }

void tmevtb_insert ( TMEVTB p_tmevtb,
EVTTIM  time 
)

time_event.c209 行で定義されています。

参照先 time_event_block::index, last_index, TMEVT_NODE, と tmevt_up.

00210 {
00211     uint_t  index;
00212 
00213     /*
00214      *  last_index をインクリメントし,そこから上に挿入位置を探す.
00215      */
00216     index = tmevt_up(++last_index, time);
00217 
00218     /*
00219      *  タイムイベントを index の位置に挿入する.
00220      */ 
00221     TMEVT_NODE(index).time = time;
00222     TMEVT_NODE(index).p_tmevtb = p_tmevtb;
00223     p_tmevtb->index = index;
00224 }


変数

time_event.c75 行で定義されています。

time_event.c92 行で定義されています。

time_event.c86 行で定義されています。

time_event.c80 行で定義されています。


Copyright © 2008 by Kijineko Inc.

ホームページ制作