task.c

タスク管理モジュール [詳細]

#include "jsp_kernel.h"
#include "task.h"
#include <cpu_context.h>

task.cのインクルード依存関係図

ソースコードを見る。

型定義

typedef void(*) TEXRTN (TEXPTN texptn, VP_INT exinf)

関数

void task_initialize ()
TCBsearch_schedtsk ()
BOOL make_runnable (TCB *tcb)
BOOL make_non_runnable (TCB *tcb)
void make_dormant (TCB *tcb)
BOOL make_active (TCB *tcb)
void exit_task ()
BOOL change_priority (TCB *tcb, UINT newpri)
BOOL rotate_ready_queue (UINT pri)
void call_texrtn ()

変数

TCBruntsk
 実行状態のタスク
TCBschedtsk
 最高優先順位のタスク
BOOL reqflg
 ディスパッチ/タスク例外処理ルーチン起動要求フラグ
BOOL enadsp
 ディスパッチ許可状態
QUEUE ready_queue [TNUM_TPRI]
 レディキュー
UINT ready_primap
 レディキューサーチのためのビットマップ


説明

タスク管理モジュール

task.c で定義されています。


型定義

typedef void(*) TEXRTN(TEXPTN texptn, VP_INT exinf)

task.c361 行で定義されています。


関数

void call_texrtn ( void   ) 

task.c369 行で定義されています。

参照先 task_control_block::enatextask_initialization_block::exinfFALSELOG_TEX_ENTERLOG_TEX_LEAVEruntskt_lock_cpu()t_sense_lockt_unlock_cpu()task_control_block::texptntask_initialization_block::texrtntask_control_block::tinibTRUE.

参照元 ena_tex()ras_tex().

00370 {
00371         TEXPTN  texptn;
00372 
00373         do {
00374                 texptn = runtsk->texptn;
00375                 runtsk->enatex = FALSE;
00376                 runtsk->texptn = 0;
00377                 t_unlock_cpu();
00378                 LOG_TEX_ENTER(texptn);
00379                 ((TEXRTN)(*runtsk->tinib->texrtn))(texptn,
00380                                                 runtsk->tinib->exinf);
00381                 LOG_TEX_LEAVE(texptn);
00382                 if (!t_sense_lock()) {
00383                         t_lock_cpu();
00384                 }
00385         } while (runtsk->texptn != 0);
00386         runtsk->enatex = TRUE;
00387 }

関数の呼び出しグラフ:

BOOL change_priority ( TCB tcb,
UINT  newpri 
)

task.c302 行で定義されています。

参照先 enadspFALSEPRIMAP_BITtask_control_block::priorityqueue_delete()queue_empty()queue_insert_prev()ready_primapready_queueschedtsksearch_schedtsk()task_control_block::task_queue.

参照元 chg_pri().

00303 {
00304         UINT    oldpri = tcb->priority;
00305 
00306         tcb->priority = newpri;
00307         queue_delete(&(tcb->task_queue));
00308         if (queue_empty(&(ready_queue[oldpri]))) {
00309                 ready_primap &= ~PRIMAP_BIT(oldpri);
00310         }
00311         queue_insert_prev(&(ready_queue[newpri]), &(tcb->task_queue));
00312         ready_primap |= PRIMAP_BIT(newpri);
00313 
00314         if (schedtsk == tcb) {
00315                 if (newpri >= oldpri) {
00316                         schedtsk = search_schedtsk();
00317                         return(schedtsk != tcb && enadsp);
00318                 }
00319         }
00320         else {
00321                 if (newpri < schedtsk->priority) {
00322                         schedtsk = tcb;
00323                         return(enadsp);
00324                 }
00325         }
00326         return(FALSE);
00327 }

関数の呼び出しグラフ:

void exit_task ( void   ) 

task.c278 行で定義されています。

参照先 task_control_block::actcntexit_and_dispatch()FALSEmake_active()make_dormant()make_non_runnable()runtsk.

参照元 ext_tsk().

00279 {
00280         make_non_runnable(runtsk);
00281         make_dormant(runtsk);
00282         if (runtsk->actcnt) {
00283                 runtsk->actcnt = FALSE;
00284                 make_active(runtsk);
00285         }
00286         exit_and_dispatch();
00287 }

関数の呼び出しグラフ:

BOOL make_active ( TCB tcb  ) 

task.c264 行で定義されています。

参照先 activate_context()make_runnable().

参照元 act_tsk()exit_task()iact_tsk()task_initialize()ter_tsk().

00265 {
00266         activate_context(tcb);
00267         return(make_runnable(tcb));
00268 }

関数の呼び出しグラフ:

void make_dormant ( TCB tcb  ) 

task.c245 行で定義されています。

参照先 create_context()task_control_block::enatexFALSEtask_initialization_block::ipriorityLOG_TSKSTATtask_control_block::prioritytask_control_block::texptntask_control_block::tinibTS_DORMANTtask_control_block::tstattask_control_block::wupcnt.

参照元 exit_task()task_initialize()ter_tsk().

00246 {
00247         tcb->priority = tcb->tinib->ipriority;
00248         tcb->tstat = TS_DORMANT;
00249         tcb->wupcnt = FALSE;
00250         tcb->enatex = FALSE;
00251         tcb->texptn = 0;
00252         create_context(tcb);
00253         LOG_TSKSTAT(tcb);
00254 }

関数の呼び出しグラフ:

BOOL make_non_runnable ( TCB tcb  ) 

task.c214 行で定義されています。

参照先 enadspFALSEqueue::nextNULLPRIMAP_BITtask_control_block::priorityqueue_delete()queue_empty()ready_primapready_queueschedtsksearch_schedtsk()task_control_block::task_queue.

参照元 dly_tsk()exit_task()make_wait()make_wait_tmout()sus_tsk()ter_tsk().

00215 {
00216         UINT    pri = tcb->priority;
00217         QUEUE   *queue = &(ready_queue[pri]);
00218 
00219         queue_delete(&(tcb->task_queue));
00220         if (queue_empty(queue)) {
00221                 ready_primap &= ~PRIMAP_BIT(pri);
00222                 if (schedtsk == tcb) {
00223                         schedtsk = (ready_primap == 0) ? (TCB * ) NULL
00224                                                 : search_schedtsk();
00225                         return(enadsp);
00226                 }
00227         }
00228         else {
00229                 if (schedtsk == tcb) {
00230                         schedtsk = (TCB *)(queue->next);
00231                         return(enadsp);
00232                 }
00233         }
00234         return(FALSE);
00235 }

関数の呼び出しグラフ:

BOOL make_runnable ( TCB tcb  ) 

task.c185 行で定義されています。

参照先 enadspFALSELOG_TSKSTATNULLPRIMAP_BITtask_control_block::priorityqueue_insert_prev()ready_primapready_queueschedtsktask_control_block::task_queueTS_RUNNABLEtask_control_block::tstat.

参照元 make_active()make_non_wait()rsm_tsk().

00186 {
00187         UINT    pri = tcb->priority;
00188 
00189         tcb->tstat = TS_RUNNABLE;
00190         LOG_TSKSTAT(tcb);
00191         queue_insert_prev(&(ready_queue[pri]), &(tcb->task_queue));
00192         ready_primap |= PRIMAP_BIT(pri);
00193 
00194         if (schedtsk == (TCB *) NULL || pri < schedtsk->priority) {
00195                 schedtsk = tcb;
00196                 return(enadsp);
00197         }
00198         return(FALSE);
00199 }

関数の呼び出しグラフ:

BOOL rotate_ready_queue ( UINT  pri  ) 

task.c340 行で定義されています。

参照先 enadspFALSEqueue::nextqueue_delete_next()queue_empty()queue_insert_prev()ready_queueschedtsk.

参照元 irot_rdq()rot_rdq().

00341 {
00342         QUEUE   *queue = &(ready_queue[pri]);
00343         QUEUE   *entry;
00344 
00345         if (!(queue_empty(queue)) && queue->next->next != queue) {
00346                 entry = queue_delete_next(queue);
00347                 queue_insert_prev(queue, entry);
00348                 if (schedtsk == (TCB *) entry) {
00349                         schedtsk = (TCB *)(queue->next);
00350                         return(enadsp);
00351                 }
00352         }
00353         return(FALSE);
00354 }

関数の呼び出しグラフ:

TCB* search_schedtsk ( void   ) 

task.c166 行で定義されています。

参照先 bitmap_search()ready_primapready_queue.

参照元 change_priority()make_non_runnable().

00167 {
00168         UINT    schedpri;
00169 
00170         schedpri = bitmap_search(ready_primap);
00171         return((TCB *)(ready_queue[schedpri].next));
00172 }

関数の呼び出しグラフ:

void task_initialize ( void   ) 

task.c88 行で定義されています。

参照先 task_control_block::actcntenadspFALSEINDEX_TSKmake_active()make_dormant()NULLqueue_initialize()ready_primapready_queuereqflgruntskschedtskTA_ACTtcb_tabletask_control_block::tinibtinib_tableTNUM_TPRITNUM_TSKtorder_tableTRUEtask_initialization_block::tskatr.

00089 {
00090         UINT    i, j;
00091         TCB     *tcb;
00092 
00093         runtsk = schedtsk = NULL;
00094         reqflg = FALSE;
00095         enadsp = TRUE;
00096 
00097         for (i = 0; i < TNUM_TPRI; i++) {
00098                 queue_initialize(&(ready_queue[i]));
00099         }
00100         ready_primap = 0;
00101 
00102         for (i = 0; i < TNUM_TSK; i++) {
00103                 j = INDEX_TSK(torder_table[i]);
00104                 tcb = &(tcb_table[j]);
00105                 tcb->tinib = &(tinib_table[j]);
00106                 tcb->actcnt = FALSE;
00107                 make_dormant(tcb);
00108                 if ((tcb->tinib->tskatr & TA_ACT) != 0) {
00109                         make_active(tcb);
00110                 }
00111         }
00112 }

関数の呼び出しグラフ:


変数

ディスパッチ許可状態

ディスパッチ許可状態である (すなわち,ディスパッチ禁止状態でない) ことを示すフラグ.

task.c69 行で定義されています。

参照元 change_priority()dis_dsp()ena_dsp()ext_tsk()make_non_runnable()make_runnable()rotate_ready_queue()sns_dpn()sns_dsp()sus_tsk()task_initialize()vxsns_dpn()vxsns_dsp().

レディキューサーチのためのビットマップ

レディキューのサーチを効率よく行うために,優先度ごとのタスクキューにタスクが入っているかどうかを示すビットマップを用意している.ビットマップを使うことで,メモリアクセスの回数を減らすことができるが, ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ちる可能性もある.

task.c82 行で定義されています。

参照元 change_priority()make_non_runnable()make_runnable()search_schedtsk()task_initialize().

QUEUE ready_queue[TNUM_TPRI]

レディキュー

レディキューは,実行できる状態のタスクを管理するためのキューである. 実行状態のタスクも管理しているため,レディ (実行可能) キューという名称は正確ではないが,レディキューという名称が定着しているため,この名称で呼ぶことにする.

レディキューは,優先度ごとのタスクキューで構成されている.タスクのTCBは,該当する優先度のキューに登録される.

task.c74 行で定義されています。

参照元 change_priority()make_non_runnable()make_runnable()rotate_ready_queue()search_schedtsk()task_initialize().

ディスパッチ/タスク例外処理ルーチン起動要求フラグ

割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたはタスク例外処理ルーチンの起動を要求することを示すフラグ.

task.c64 行で定義されています。

参照元 iact_tsk()ifsnd_dtq()ipsnd_dtq()iras_tex()irel_wai()irot_rdq()iset_flg()isig_sem()iwup_tsk()task_initialize()wait_tmout()wait_tmout_ok().

実行状態のタスク

実行状態のタスク (=プロセッサがコンテキストを持っているタスク) の TCB を指すポインタ.実行状態のタスクがない場合は NULL にする. サービスコールの処理中で,自タスク (サービスコールを呼び出したタスク) に関する情報を参照する場合は runtsk を使う.runtsk を書き換えるのは,ディスパッチャ (と初期化処理) のみである.

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

参照元 call_texrtn()dis_tex()dly_tsk()ena_dsp()ena_tex()exit_task()get_tid()iget_tid()iras_tex()make_wait()make_wait_tmout()ras_tex()rcv_dtq()rot_rdq()slp_tsk()sns_tex()sus_tsk()task_initialize()trcv_dtq()tslp_tsk()vxsns_tex()wobj_make_wait()wobj_make_wait_tmout()wobj_queue_insert().

最高優先順位のタスク

実行できるタスクの中で最高優先順位のタスクの TCB を指すポインタ.実行できるタスクがない場合は NULL にする. ディスパッチ禁止状態など,ディスパッチが保留されている間は,runtsk と一致しているとは限らない.

task.c59 行で定義されています。

参照元 change_priority()ena_dsp()make_non_runnable()make_runnable()rotate_ready_queue()task_initialize().


Copyright © 2006 by TAKAGI Nobuhisa.
Copyright © 2006 by Kijineko Inc..
このページは Mon Dec 18 17:20:44 2006 に Doxygen によって生成されました。
データ入力からプログラム開発まで!様々なスキルを持ったメンバーが登録しています【@SOHO】