task.c

説明を見る。
00001 /*
00002  *  TOPPERS/FDMP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Function Distributed Multiprocessor Kernel
00005  * 
00006  *  Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  *  Copyright (C) 2005-2006 by Embedded and Real-Time Systems Laboratory
00009  *              Graduate School of Information Science, Nagoya Univ., JAPAN
00010  * 
00011  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00012  *  によって公表されている GNU General Public License の Version 2 に記
00013  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00014  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00015  *  利用と呼ぶ)することを無償で許諾する.
00016  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00017  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00018  *      スコード中に含まれていること.
00019  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00020  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00021  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00022  *      の無保証規定を掲載すること.
00023  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00024  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00025  *      と.
00026  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00027  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00028  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00029  *        報告すること.
00030  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00031  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00032  * 
00033  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00034  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00035  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00036  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00037  * 
00038  *  @(#) $Id: task.c,v 1.3 2006/03/14 04:37:54 honda Exp $
00039  */
00040 
00045 #include "fdmp_kernel.h"
00046 #include "task.h"
00047 #include "cpu_context.h"
00048 
00049 #ifdef __tskini
00050 
00054 TCB     *runtsk;
00055 
00059 TCB     *schedtsk;
00060 
00064 BOOL    reqflg;
00065 
00069 BOOL    enadsp;
00070 
00074 QUEUE   ready_queue[TNUM_TPRI];
00075 
00082 UINT    ready_primap;
00083 
00084 
00089 void
00090 task_initialize()
00091 {
00092     UINT    i;
00093     TCB     *tcb;
00094 
00095     runtsk = schedtsk = NULL;
00096     runccb = my_local_ccb; /* 現時点では意味無し */
00097     reqflg = FALSE;
00098     enadsp = TRUE;
00099 
00100     for (i = 0; i < TNUM_TPRI; i++) {
00101         queue_initialize(&(ready_queue[i]));
00102     }
00103     ready_primap = 0;
00104 
00105     for (i = 0; i < MY_TNUM_TSK; i++) {
00106         tcb = &(tcb_table[i]);
00107         tcb->tinib = &(tinib_table[i]);
00108         tcb->actcnt = FALSE;
00109 
00110         tcb->clsid = CLS_MY_LOCAL;
00111         tcb->pend_chgpri = FALSE;
00112         tcb->pend_tertsk = FALSE;
00113         tcb->pend_relwai = FALSE;
00114         tcb->terflg = FALSE;
00115         
00116         make_dormant(tcb);
00117     }
00118 
00119     my_local_exccb->p_ready_queue = &ready_queue[0];
00120     my_local_exccb->p_ready_primap = &ready_primap; 
00121     my_local_exccb->p_runtsk = &runtsk;
00122     my_local_exccb->p_schedtsk = &schedtsk;
00123     my_local_exccb->p_enadsp = &enadsp;
00124     
00125     my_local_exccb->tsk.cb_table = &tcb_table[0];
00126     my_local_exccb->tsk.max_id = tmax_tskid;
00127 
00128     my_local_exccb->p_activate_r = activate_r;  
00129 }
00130 
00131 #endif /* __tskini */
00132 
00133 
00139 #ifdef __tskiniact
00140 
00141 void
00142 task_init_activate()
00143 {
00144     UINT i, j;
00145     TCB     *tcb;
00146     
00147     for (i = 0; i < MY_TNUM_TSK; i++) {
00148         j = INDEX_TSK(torder_table[i]);
00149         tcb = &(tcb_table[j]);      
00150         if ((tcb->tinib->tskatr & TA_ACT) != 0) {
00151             make_active(my_local_ccb, tcb);
00152         }
00153     }
00154 }
00155 
00156 #endif /* __tskiniact */
00157 
00175 #ifndef PRIMAP_BIT
00176 #define PRIMAP_BIT(pri)     (1u << (pri))
00177 #endif /* PRIMAP_BIT */
00178 
00179 #ifndef CPU_BITMAP_SEARCH
00180 
00181 Inline UINT
00182 bitmap_search(UINT bitmap)
00183 {
00184     static const VB search_table[] = { 0, 1, 0, 2, 0, 1, 0,
00185                     3, 0, 1, 0, 2, 0, 1, 0 };
00186     INT n = 0;
00187 
00188     assert((bitmap & 0xffff) != 0);
00189     if ((bitmap & 0x00ff) == 0) {
00190         bitmap >>= 8;
00191         n += 8;
00192     }
00193     if ((bitmap & 0x0f) == 0) {
00194         bitmap >>= 4;
00195         n += 4;
00196     }
00197     return(n + search_table[(bitmap & 0x0f) - 1]);
00198 }
00199 
00200 #endif /* CPU_BITMAP_SEARCH */
00201 
00202 
00206 #ifdef __tsksched
00207 
00208 TCB *
00209 search_schedtsk(CCB *ccb)
00210 {
00211     UINT    schedpri;
00212 
00213     schedpri = bitmap_search(*(ccb->p_ready_primap));
00214     return((TCB *)(ccb->p_ready_queue[schedpri].next));
00215 }
00216 
00217 #endif /* __tsksched */
00218 
00225 #ifdef __tskrun
00226 
00227 BOOL
00228 make_runnable(CCB *ccb, TCB *tcb)
00229 {
00230     UINT    pri = tcb->priority;
00231     
00232     tcb->tstat = TS_RUNNABLE;
00233     LOG_TSKSTAT(tcb);      
00234     queue_insert_prev(&(ccb->p_ready_queue[pri]), &(tcb->task_queue));
00235     *(ccb->p_ready_primap) |= PRIMAP_BIT(pri);
00236     
00237     if (*(ccb->p_schedtsk) == (TCB *) NULL || pri < (*(ccb->p_schedtsk))->priority){
00238         *(ccb->p_schedtsk) = tcb;
00239         return(*(ccb->p_enadsp));
00240     }
00241     return(FALSE);
00242 }
00243 
00244 #endif /* __tskrun */
00245 
00254 #ifdef __tsknrun
00255 
00256 BOOL
00257 make_non_runnable(CCB *ccb, TCB *tcb)
00258 {
00259     UINT    pri = tcb->priority;
00260     QUEUE   *queue = &(ccb->p_ready_queue[pri]);
00261     
00262     queue_delete(&(tcb->task_queue));
00263     if (queue_empty(queue)) {
00264         *(ccb->p_ready_primap) &= ~PRIMAP_BIT(pri);
00265         if (*(ccb->p_schedtsk) == tcb) {
00266             *(ccb->p_schedtsk) = (*(ccb->p_ready_primap) == 0) ? (TCB * ) NULL
00267               : search_schedtsk(ccb);
00268             return(*(ccb->p_enadsp));
00269         }
00270     }
00271     else {
00272         if (*(ccb->p_schedtsk) == tcb) {
00273             *(ccb->p_schedtsk) = (TCB *)(queue->next);
00274             return(*(ccb->p_enadsp));
00275         }
00276     }
00277     return(FALSE);
00278 }
00279 
00280 #endif /* __tsknrun */
00281 
00285 #ifdef __tskdmt
00286 
00287 void
00288 make_dormant(TCB *tcb)
00289 {
00290     tcb->priority = tcb->tinib->ipriority;
00291     tcb->tstat = TS_DORMANT;
00292     tcb->wupcnt = FALSE;
00293     tcb->enatex = FALSE;
00294     tcb->texptn = 0;
00295     tcb->pend_chgpri = FALSE;
00296     tcb->pend_tertsk = FALSE;
00297     tcb->pend_relwai = FALSE;
00298     LOG_TSKSTAT(tcb);
00299 }
00300 
00301 #endif /* __tskdmt */
00302 
00306 #ifdef __tskact
00307 
00308 BOOL
00309 make_active(CCB *ccb, TCB *tcb)
00310 {
00311     activate_context(ccb, tcb);
00312     return(make_runnable(ccb,tcb));
00313 }
00314 
00315 #endif /* __tskact */
00316 
00322 #ifdef __tskdisreq
00323 
00324 BOOL
00325 dispatch_request(INT prcid)
00326 {
00327     if (prcid != 0 && prcid != PRCID) { 
00328         raise_ipi(prcid);
00329         return(FALSE);
00330     }
00331     return(TRUE);
00332 }
00333 
00334 #endif /* __tskdisreq */
00335 
00344 #ifdef __tskpri
00345 
00346 BOOL
00347 change_priority(CCB *ccb, TCB *tcb, UINT newpri)
00348 {
00349     UINT    oldpri = tcb->priority;
00350 
00351     tcb->priority = newpri;
00352     queue_delete(&(tcb->task_queue));
00353     if (queue_empty(&(ccb->p_ready_queue[oldpri]))) {
00354         *(ccb->p_ready_primap) &= ~PRIMAP_BIT(oldpri);
00355     }
00356     queue_insert_prev(&(ccb->p_ready_queue[newpri]), &(tcb->task_queue));
00357     *(ccb->p_ready_primap) |= PRIMAP_BIT(newpri);
00358 
00359     if (*(ccb->p_schedtsk) == tcb) {
00360         if (newpri >= oldpri) {
00361             *(ccb->p_schedtsk) = search_schedtsk(ccb);
00362             return(*(ccb->p_schedtsk) != tcb && *(ccb->p_enadsp));
00363         }
00364     }
00365     else {
00366         if (newpri < (*ccb->p_schedtsk)->priority) {
00367             *(ccb->p_schedtsk) = tcb;
00368             return(*(ccb->p_enadsp));
00369         }
00370     }
00371     return(FALSE);
00372 }
00373 
00374 #endif /* __tskpri */
00375 
00382 #ifdef __tskrot
00383 
00384 BOOL
00385 rotate_ready_queue(CCB *ccb,UINT pri)
00386 {
00387     QUEUE   *queue = &(ccb->p_ready_queue[pri]);
00388     QUEUE   *entry;
00389 
00390     if (!(queue_empty(queue)) && queue->next->next != queue) {
00391         entry = queue_delete_next(queue);
00392         queue_insert_prev(queue, entry);
00393         if (*(ccb->p_schedtsk) == (TCB *) entry) {
00394             *(ccb->p_schedtsk) = (TCB *)(queue->next);
00395             return(*(ccb->p_enadsp));
00396         }
00397     }
00398     return(FALSE);
00399 }
00400 
00401 #endif /* __tskrot */
00402 
00406 typedef void    (*TEXRTN)(TEXPTN texptn, VP_INT exinf);
00407 
00408 
00412 #ifdef __tsktex
00413 
00414 void
00415 call_texrtn()
00416 {
00417     TEXPTN  texptn;
00418     
00419     do {        
00420         texptn = runtsk->texptn;
00421         runtsk->enatex = FALSE;
00422         runtsk->texptn = 0;
00423         T_RELEASE_LOCK(runccb->tsk_lock);
00424 
00425         LOG_TEX_ENTER(texptn);
00426         ((TEXRTN)(*runtsk->tinib->texrtn))(texptn,
00427                         runtsk->tinib->exinf);
00428         /*
00429          * タスク例外処理ルーチンからCPUロック状態で
00430          * 戻ってきたときの対処
00431          */
00432         if (t_sense_lock()) {
00433             t_unlock_cpu();
00434         }
00435         LOG_TEX_LEAVE(texptn);
00436 
00437       retry:
00438         T_ACQUIRE_LOCK(runccb->tsk_lock);
00439     } while (runtsk->texptn != 0);
00440     runtsk->enatex = TRUE;
00441 }
00442 
00443 
00448 void
00449 dispatch_call_texrtn()
00450 {
00451   retry:
00452     if (ACQUIRE_LOCK(runccb->tsk_lock)) {
00453         t_unlock_cpu();
00454         t_lock_cpu();
00455         goto retry;
00456     }
00457     if (runtsk->enatex && runtsk->texptn != 0) {
00458         call_texrtn();
00459     }
00460     RELEASE_LOCK(runccb->tsk_lock);
00461 }
00462 
00463 /*
00464  *  タスク例外処理ルーチンの起動
00465  */
00466 #ifndef OMIT_CALLTEX
00467 
00468 void
00469 calltex()
00470 {
00471     if (runtsk->enatex && runtsk->texptn != 0) {
00472         dispatch_call_texrtn();
00473     }
00474 }
00475 
00476 #endif /* OMIT_CALLTEX */
00477 #endif /* __tsktex */

Copyright © 2006 by TAKAGI Nobuhisa.
このページは Mon Apr 3 23:49:13 2006 に Doxygen によって生成されました。