task.c

#include "kernel_impl.h"
#include "wait.h"
#include "task.h"

ソースコードを見る。

マクロ定義

#define LOG_TEX_ENTER(texptn)
#define LOG_TEX_LEAVE(texptn)
#define PRIMAP_BIT(pri)   (1U << (pri))

関数

void initialize_task (void)
Inline uint_t bitmap_search (uint16_t bitmap)
Inline bool_t primap_empty (void)
Inline uint_t primap_search (void)
Inline void primap_set (uint_t pri)
Inline void primap_clear (uint_t pri)
TCBsearch_schedtsk (void)
bool_t make_runnable (TCB *p_tcb)
bool_t make_non_runnable (TCB *p_tcb)
void make_dormant (TCB *p_tcb)
bool_t make_active (TCB *p_tcb)
bool_t change_priority (TCB *p_tcb, uint_t newpri)
bool_t rotate_ready_queue (uint_t pri)
void call_texrtn (void)
void calltex (void)

変数

TCBp_runtsk
TCBp_schedtsk
bool_t reqflg
bool_t disdsp
bool_t dspflg
QUEUE ready_queue [TNUM_TPRI]
uint16_t ready_primap
static const unsigned char bitmap_search_table []


マクロ定義

#define LOG_TEX_ENTER ( texptn   ) 

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

参照元 call_texrtn().

#define LOG_TEX_LEAVE ( texptn   ) 

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

参照元 call_texrtn().

#define PRIMAP_BIT ( pri   )     (1U << (pri))

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


関数

Inline uint_t bitmap_search ( uint16_t  bitmap  ) 

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

参照先 assert, と bitmap_search_table.

00165 {
00166     uint_t  n = 0U;
00167 
00168     assert(bitmap != 0U);
00169     if ((bitmap & 0x00ffU) == 0U) {
00170         bitmap >>= 8;
00171         n += 8;
00172     }
00173     if ((bitmap & 0x0fU) == 0U) {
00174         bitmap >>= 4;
00175         n += 4;
00176     }
00177     return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
00178 }

void call_texrtn ( void   ) 

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

参照先 disdsp, dispatch, dspflg, task_control_block::enatex, task_initialization_block::exinf, LOG_TEX_ENTER, LOG_TEX_LEAVE, task_control_block::p_tinib, t_get_ipm, t_lock_cpu, t_sense_lock, t_set_ipm, t_unlock_cpu, task_control_block::texptn, と task_initialization_block::texrtn.

00428 {
00429     TEXPTN  texptn;
00430     PRI     saved_ipm;
00431     bool_t  saved_disdsp, saved_dspflg;
00432 
00433     saved_ipm = t_get_ipm();
00434     saved_disdsp = disdsp;
00435     saved_dspflg = dspflg;
00436     do {
00437         texptn = p_runtsk->texptn;
00438         p_runtsk->enatex = false;
00439         p_runtsk->texptn = 0U;
00440 
00441         t_unlock_cpu();
00442         LOG_TEX_ENTER(texptn);
00443         (*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
00444                                                 p_runtsk->p_tinib->exinf);
00445         LOG_TEX_LEAVE(texptn);
00446         if (!t_sense_lock()) {
00447             t_lock_cpu();
00448         }
00449         t_set_ipm(saved_ipm);
00450         disdsp = saved_disdsp;
00451         dspflg = saved_dspflg;
00452         if (p_runtsk != p_schedtsk && dspflg) {
00453             dispatch();
00454         }
00455     } while (p_runtsk->texptn != 0U);
00456     p_runtsk->enatex = true;
00457 }

void calltex ( void   ) 

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

参照先 call_texrtn, task_control_block::enatex, と task_control_block::texptn.

00468 {
00469     if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
00470         call_texrtn();
00471     }
00472 }

bool_t change_priority ( TCB p_tcb,
uint_t  newpri 
)

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

参照先 dspflg, task_control_block::p_winfo, primap_clear(), primap_set(), task_control_block::priority, queue_delete(), queue_empty(), queue_insert_prev(), search_schedtsk, task_control_block::task_queue, task_control_block::tstat, TSTAT_RUNNABLE, TSTAT_WAIT_WOBJCB, と wobj_change_priority().

00345 {
00346     uint_t  oldpri;
00347 
00348     oldpri = p_tcb->priority;
00349     p_tcb->priority = newpri;
00350 
00351     if (TSTAT_RUNNABLE(p_tcb->tstat)) {
00352         /*
00353          *  タスクが実行できる状態の場合
00354          */
00355         queue_delete(&(p_tcb->task_queue));
00356         if (queue_empty(&(ready_queue[oldpri]))) {
00357             primap_clear(oldpri);
00358         }
00359         queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
00360         primap_set(newpri);
00361 
00362         if (p_schedtsk == p_tcb) {
00363             if (newpri >= oldpri) {
00364                 p_schedtsk = search_schedtsk();
00365                 return(p_schedtsk != p_tcb && dspflg);
00366             }
00367         }
00368         else {
00369             if (newpri < p_schedtsk->priority) {
00370                 p_schedtsk = p_tcb;
00371                 return(dspflg);
00372             }
00373         }
00374     }
00375     else {
00376         if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
00377             /*
00378              *  タスクが,同期・通信オブジェクトの管理ブロックの共通部
00379              *  分(WOBJCB)の待ちキューにつながれている場合
00380              */
00381             wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
00382                                                                     p_tcb);
00383         }
00384     }
00385     return(false);
00386 }

void initialize_task ( void   ) 

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

参照先 task_control_block::actque, disdsp, dspflg, INDEX_TSK, make_active, make_dormant, NULL, task_control_block::p_tinib, queue_initialize(), ready_primap, reqflg, TA_ACT, tcb_table, tinib_table, TNUM_TPRI, tnum_tsk, torder_table, と task_initialization_block::tskatr.

00107 {
00108     uint_t  i, j;
00109     TCB     *p_tcb;
00110 
00111     p_runtsk = p_schedtsk = NULL;
00112     reqflg = false;
00113     disdsp = false;
00114     dspflg = true;
00115 
00116     for (i = 0; i < TNUM_TPRI; i++) {
00117         queue_initialize(&(ready_queue[i]));
00118     }
00119     ready_primap = 0U;
00120 
00121     for (i = 0; i < tnum_tsk; i++) {
00122         j = INDEX_TSK(torder_table[i]);
00123         p_tcb = &(tcb_table[j]);
00124         p_tcb->p_tinib = &(tinib_table[j]);
00125         p_tcb->actque = false;
00126         make_dormant(p_tcb);
00127         if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
00128             make_active(p_tcb);
00129         }
00130     }
00131 }

bool_t make_active ( TCB p_tcb  ) 

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

参照先 activate_context, と make_runnable.

00322 {
00323     activate_context(p_tcb);
00324     return(make_runnable(p_tcb));
00325 }

void make_dormant ( TCB p_tcb  ) 

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

参照先 task_control_block::enatex, task_initialization_block::ipriority, LOG_TSKSTAT, task_control_block::p_tinib, task_control_block::priority, task_control_block::texptn, TS_DORMANT, task_control_block::tstat, と task_control_block::wupque.

00304 {
00305     p_tcb->tstat = TS_DORMANT;
00306     p_tcb->priority = p_tcb->p_tinib->ipriority;
00307     p_tcb->wupque = false;
00308     p_tcb->enatex = false;
00309     p_tcb->texptn = 0U;
00310     LOG_TSKSTAT(p_tcb);
00311 }

bool_t make_non_runnable ( TCB p_tcb  ) 

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

参照先 dspflg, NULL, queue::p_next, primap_clear(), primap_empty(), task_control_block::priority, queue_delete(), queue_empty(), search_schedtsk, と task_control_block::task_queue.

00274 {
00275     uint_t  pri = p_tcb->priority;
00276     QUEUE   *p_queue = &(ready_queue[pri]);
00277 
00278     queue_delete(&(p_tcb->task_queue));
00279     if (queue_empty(p_queue)) {
00280         primap_clear(pri);
00281         if (p_schedtsk == p_tcb) {
00282             p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
00283             return(dspflg);
00284         }
00285     }
00286     else {
00287         if (p_schedtsk == p_tcb) {
00288             p_schedtsk = (TCB *)(p_queue->p_next);
00289             return(dspflg);
00290         }
00291     }
00292     return(false);
00293 }

bool_t make_runnable ( TCB p_tcb  ) 

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

参照先 dspflg, LOG_TSKSTAT, NULL, primap_set(), task_control_block::priority, queue_insert_prev(), task_control_block::task_queue, TS_RUNNABLE, と task_control_block::tstat.

00245 {
00246     uint_t  pri = p_tcb->priority;
00247 
00248     p_tcb->tstat = TS_RUNNABLE;
00249     LOG_TSKSTAT(p_tcb);
00250     queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
00251     primap_set(pri);
00252 
00253     if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
00254         p_schedtsk = p_tcb;
00255         return(dspflg);
00256     }
00257     return(false);
00258 }

Inline void primap_clear ( uint_t  pri  ) 

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

参照先 PRIMAP_BIT, と ready_primap.

参照元 change_priority(), と make_non_runnable().

00214 {
00215     ready_primap &= ~PRIMAP_BIT(pri);
00216 }

Inline bool_t primap_empty ( void   ) 

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

参照先 ready_primap.

参照元 make_non_runnable().

00187 {
00188     return(ready_primap == 0U);
00189 }

Inline uint_t primap_search ( void   ) 

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

参照先 bitmap_search(), と ready_primap.

参照元 search_schedtsk().

00196 {
00197     return(bitmap_search(ready_primap));
00198 }

Inline void primap_set ( uint_t  pri  ) 

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

参照先 PRIMAP_BIT, と ready_primap.

参照元 change_priority(), と make_runnable().

00205 {
00206     ready_primap |= PRIMAP_BIT(pri);
00207 }

bool_t rotate_ready_queue ( uint_t  pri  ) 

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

参照先 dspflg, queue::p_next, queue_delete_next(), queue_empty(), と queue_insert_prev().

00400 {
00401     QUEUE   *p_queue = &(ready_queue[pri]);
00402     QUEUE   *p_entry;
00403 
00404     if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
00405         p_entry = queue_delete_next(p_queue);
00406         queue_insert_prev(p_queue, p_entry);
00407         if (p_schedtsk == (TCB *) p_entry) {
00408             p_schedtsk = (TCB *)(p_queue->p_next);
00409             return(dspflg);
00410         }
00411     }
00412     return(false);
00413 }

TCB* search_schedtsk ( void   ) 

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

参照先 primap_search().

00225 {
00226     uint_t  schedpri;
00227 
00228     schedpri = primap_search();
00229     return((TCB *)(ready_queue[schedpri].p_next));
00230 }


変数

const unsigned char bitmap_search_table[] [static]

初期値:

 { 0, 1, 0, 2, 0, 1, 0,
                                                3, 0, 1, 0, 2, 0, 1, 0 }

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

参照元 bitmap_search().

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

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

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

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

uint16_t ready_primap

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

QUEUE ready_queue[TNUM_TPRI]

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

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


Copyright © 2008 by Kijineko Inc.

ホームページ制作