wait.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: wait.c,v 1.3 2006/03/14 04:37:54 honda Exp $
00039  */
00040 
00045 #include "fdmp_kernel.h"
00046 #include "wait.h"
00047 
00053 #ifdef __waimake
00054 
00055 void
00056 make_wait_tmout(WINFO *winfo, TMEVTB *tmevtb, TMO tmout)
00057 {
00058     make_non_runnable(runccb, runtsk);
00059     runtsk->winfo = winfo;
00060     if (tmout > 0) {
00061         winfo->tmevtb = tmevtb;
00062         tmevtb_enqueue(runccb, tmevtb, (RELTIM) tmout,
00063                        (CBACK) wait_tmout, (VP) runtsk);
00064     }
00065     else {
00066         assert(tmout == TMO_FEVR);
00067         winfo->tmevtb = NULL;
00068     }
00069 }
00070 
00071 #endif /* __waimake */
00072 
00084 Inline BOOL
00085 make_non_wait(CCB *ccb, TCB *tcb)
00086 {
00087     assert(TSTAT_WAITING(tcb->tstat));
00088     
00089     /* タスク強制終了保留チェック */
00090     if (tcb->pend_tertsk) {
00091         /*
00092          * TCBを解放して,terflgをTRUEにする.
00093          * pend_tertskはmake_dormant()でクリアされる 
00094          */ 
00095         make_dormant(tcb);     
00096         tcb->terflg = TRUE;
00097         if (tcb->actcnt) {
00098             tcb->actcnt = FALSE;
00099             if (make_active(ccb, tcb)) {
00100                 return(TRUE);
00101             }
00102         }
00103         return(FALSE);
00104     }
00105     
00106     /* 優先度変更フラグチェック */
00107     if (tcb->pend_chgpri) {
00108         tcb->priority = tcb->pend_newpri;
00109         /*  優先度変更フラグのクリア  */
00110         tcb->pend_chgpri = FALSE;
00111     }
00112 
00113     /* タスク強制待ち解除保留クリア */
00114     tcb->pend_relwai = FALSE;
00115     
00116     if (!(TSTAT_SUSPENDED(tcb->tstat))) {
00117         /*
00118          *  待ち状態から実行できる状態への遷移
00119          */
00120         return(make_runnable(ccb, tcb));
00121     }
00122     else {
00123         /*
00124          *  二重待ち状態から強制待ち状態への遷移
00125          */
00126         tcb->tstat = TS_SUSPENDED;
00127         LOG_TSKSTAT(tcb);
00128         return(FALSE);
00129     }
00130 }
00131 
00132 
00136 #ifdef __waicmp
00137 
00138 BOOL
00139 wait_complete(CCB *ccb, TCB *tcb)
00140 {
00141     if (tcb->winfo->tmevtb != NULL) {
00142         tmevtb_dequeue(ccb, tcb->winfo->tmevtb);
00143     }
00144     tcb->winfo->wercd = E_OK;
00145     return(make_non_wait(ccb, tcb));
00146 }
00147 
00148 #endif /* __waicmp */
00149 
00165 #ifdef __waitmo
00166 
00167 void
00168 wait_tmout(TCB *tcb)
00169 {
00170     CCB     *occb;
00171     
00172     assert(get_ccb(tcb->clsid) == my_local_ccb);
00173 
00174     if ((tcb->tstat & TS_WAIT_WOBJ) != 0) {
00175         /* オブジェクト待ちの場合 */
00176         occb = ((WINFO_WOBJ *)tcb->winfo)->ccb;
00177         tcb->pend_relwai = TRUE;
00178         I_RELEASE_LOCK(my_local_ccb->tsk_lock);
00179 
00180         /*
00181          *  あらためて
00182          *  オブジェクトロック -> タスクロック
00183          *  の順でロックを取得 
00184          */
00185       retry:
00186         I_ACQUIRE_LOCK(occb->obj_lock);
00187         I_ACQUIRE_NESTED_LOCK(my_local_ccb->tsk_lock, occb->obj_lock);
00188         
00189         /* タスクの状態が変化していないかチェック */
00190         if (!(tcb->pend_relwai)) {
00191             /* 既に他の箇所で待ち解除処理がなされた */
00192             RELEASE_LOCK(occb->obj_lock);
00193             return;
00194         }
00195         tcb->pend_relwai = FALSE;
00196         queue_delete(&(tcb->task_queue));
00197         RELEASE_LOCK(occb->obj_lock);       
00198     }
00199     tcb->winfo->wercd = E_TMOUT;
00200     if (make_non_wait(my_local_ccb, tcb)) {
00201         reqflg = TRUE;
00202     }       
00203 }
00204 
00205 #endif /* __waitmo */
00206 
00210 #ifdef __waitmook
00211 
00212 void
00213 wait_tmout_ok(TCB *tcb)
00214 {
00215     assert(get_ccb(tcb->clsid) == my_local_ccb);
00216 
00217     tcb->winfo->wercd = E_OK;
00218     if (make_non_wait(my_local_ccb, tcb)) {
00219         reqflg = TRUE;
00220     }
00221 }
00222 
00223 #endif /* __waitmook */
00224 
00228 #ifdef __waican
00229 
00230 void
00231 wait_cancel(CCB *ccb, TCB *tcb)
00232 {
00233     if (tcb->winfo->tmevtb != NULL) {
00234         tmevtb_dequeue((VP) ccb, tcb->winfo->tmevtb);
00235     }
00236     if ((tcb->tstat & TS_WAIT_WOBJ) != 0) {
00237         queue_delete(&(tcb->task_queue));
00238     }
00239 }
00240 
00241 #endif /* __waican */
00242 
00246 #ifdef __wairel
00247 
00248 BOOL
00249 wait_release(CCB *ccb, TCB *tcb)
00250 {
00251     wait_cancel(ccb, tcb);
00252     tcb->winfo->wercd = E_RLWAI;
00253     return(make_non_wait(ccb, tcb));
00254 }
00255 
00256 #endif /* __wairel */
00257 
00261 Inline void
00262 queue_insert_tpri(TCB *tcb, QUEUE *queue)
00263 {
00264     QUEUE   *entry;
00265     UINT    priority = tcb->priority;
00266 
00267     for (entry = queue->next; entry != queue; entry = entry->next) {
00268         if (priority < ((TCB *) entry)->priority) {
00269             break;
00270         }
00271     }
00272     queue_insert_prev(entry, &(tcb->task_queue));
00273 }
00274 
00275 
00279 Inline void
00280 wobj_queue_insert(WOBJCB *wobjcb)
00281 {
00282     if ((wobjcb->wobjinib->wobjatr & TA_TPRI) != 0) {
00283         queue_insert_tpri(runtsk, &(wobjcb->wait_queue));
00284     }
00285     else {
00286         queue_insert_prev(&(wobjcb->wait_queue),
00287                     &(runtsk->task_queue));
00288     }
00289 }
00290 
00291 
00296 #ifdef __wobjwai
00297 
00298 void
00299 wobj_make_wait(CCB *ccb, WOBJCB *wobjcb, WINFO_WOBJ *winfo)
00300 {
00301     runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ | TS_WAIT_WOBJCB);
00302     make_wait(&(winfo->winfo));
00303     wobj_queue_insert(wobjcb);
00304     winfo->ccb = ccb;
00305     winfo->wobjcb = wobjcb;
00306     LOG_TSKSTAT(runtsk);
00307 }
00308 
00309 #endif /* __wobjwai */
00310 
00311 #ifdef __wobjwaitmo
00312 
00313 void
00314 wobj_make_wait_tmout(CCB *ccb, WOBJCB *wobjcb, WINFO_WOBJ *winfo,
00315                     TMEVTB *tmevtb, TMO tmout)
00316 {
00317     runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ | TS_WAIT_WOBJCB);
00318     make_wait_tmout(&(winfo->winfo), tmevtb, tmout);
00319     wobj_queue_insert(wobjcb);
00320     winfo->ccb = ccb;   
00321     winfo->wobjcb = wobjcb;
00322     LOG_TSKSTAT(runtsk);
00323 }
00324 
00325 #endif /* __wobjwaitmo */
00326 
00330 #ifdef __wobjpri
00331 
00332 void
00333 wobj_change_priority(WOBJCB *wobjcb, TCB *tcb)
00334 {
00335     if ((wobjcb->wobjinib->wobjatr & TA_TPRI) != 0) {
00336         queue_delete(&(tcb->task_queue));
00337         queue_insert_tpri(tcb, &(wobjcb->wait_queue));
00338     }
00339 }
00340 
00341 #endif /* __wobjpri */

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