time_event.h

ソースコードを見る。

データ構造

struct  time_event_block
struct  time_event_node

マクロ定義

#define TMAX_RELTIM   ((RELTIM) LONG_MAX)
#define base_time   (next_time + (next_subtime > 0U ? 1U : 0U))

型定義

typedef ulong_t EVTTIM
typedef void(* CBACK )(void *)
typedef struct time_event_block TMEVTB
typedef struct time_event_node TMEVTN

関数

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_enqueue (TMEVTB *p_tmevtb, RELTIM time, CBACK callback, void *arg)
Inline void tmevtb_enqueue_evttim (TMEVTB *p_tmevtb, EVTTIM time, CBACK callback, void *arg)
Inline void tmevtb_dequeue (TMEVTB *p_tmevtb)
RELTIM tmevt_lefttim (TMEVTB *p_tmevtb)
void signal_time (void)

変数

TMEVTN tmevt_heap []
EVTTIM current_time
EVTTIM next_time
uint_t next_subtime
uint_t last_index


マクロ定義

#define base_time   (next_time + (next_subtime > 0U ? 1U : 0U))

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

参照元 sta_cyc(), tmevt_lefttim(), と tmevtb_enqueue().

#define TMAX_RELTIM   ((RELTIM) LONG_MAX)

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

参照元 dly_tsk(), ista_alm(), sta_alm(), と tmevtb_enqueue().


型定義

typedef void(* CBACK)(void *)

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

typedef ulong_t EVTTIM

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

typedef struct time_event_block TMEVTB

typedef struct time_event_node TMEVTN


関数

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_dequeue ( TMEVTB p_tmevtb  ) 

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

参照先 tmevtb_delete.

参照元 ista_alm(), istp_alm(), sta_alm(), sta_cyc(), stp_alm(), stp_cyc(), と wait_dequeue_tmevtb().

00190 {
00191     tmevtb_delete(p_tmevtb);
00192 }

Inline void tmevtb_enqueue ( TMEVTB p_tmevtb,
RELTIM  time,
CBACK  callback,
void *  arg 
)

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

参照先 time_event_block::arg, assert, base_time, time_event_block::callback, TMAX_RELTIM, と tmevtb_insert.

参照元 dly_tsk(), ista_alm(), make_wait_tmout(), と sta_alm().

00163 {
00164     assert(time <= TMAX_RELTIM);
00165 
00166     p_tmevtb->callback = callback;
00167     p_tmevtb->arg = arg;
00168     tmevtb_insert(p_tmevtb, base_time + time);
00169 }

Inline void tmevtb_enqueue_evttim ( TMEVTB p_tmevtb,
EVTTIM  time,
CBACK  callback,
void *  arg 
)

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

参照先 time_event_block::arg, time_event_block::callback, と tmevtb_insert.

参照元 tmevtb_enqueue_cyc().

00179 {
00180     p_tmevtb->callback = callback;
00181     p_tmevtb->arg = arg;
00182     tmevtb_insert(p_tmevtb, time);
00183 }

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.

ホームページ制作