wait.c

説明を見る。
00001 /*
00002  *  TOPPERS/JSP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Just Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  * 
00009  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00010  *  によって公表されている GNU General Public License の Version 2 に記
00011  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00012  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00013  *  利用と呼ぶ)することを無償で許諾する.
00014  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00015  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00016  *      スコード中に含まれていること.
00017  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00018  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00019  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00020  *      の無保証規定を掲載すること.
00021  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00022  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00023  *      と.
00024  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00025  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00026  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00027  *        報告すること.
00028  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00029  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00030  * 
00031  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00032  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00033  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00034  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00035  * 
00036  *  @(#) $Id: wait.c,v 1.6 2003/06/04 01:46:16 hiro Exp $
00037  */
00038 
00039 /*
00040  *      待ち状態管理モジュール
00041  */
00042 
00043 #include "jsp_kernel.h"
00044 #include "wait.h"
00045 
00046 /*
00047  *  待ち状態への移行(タイムアウト指定)
00048  *
00049  */
00050 #ifdef __waimake
00051 
00052 void
00053 make_wait_tmout(WINFO *winfo, TMEVTB *tmevtb, TMO tmout)
00054 {
00055         make_non_runnable(runtsk);
00056         runtsk->winfo = winfo;
00057         if (tmout > 0) {
00058                 winfo->tmevtb = tmevtb;
00059                 tmevtb_enqueue(tmevtb, (RELTIM) tmout,
00060                                         (CBACK) wait_tmout, (VP) runtsk);
00061         }
00062         else {
00063                 assert(tmout == TMO_FEVR);
00064                 winfo->tmevtb = NULL;
00065         }
00066 }
00067 
00068 #endif /* __waimake */
00069 
00070 /*
00071  *  待ち解除のためのタスク状態の更新
00072  *
00073  *  tcb で指定されるタスクを,待ち解除するようタスク状態を更新する.待
00074  *  ち解除するタスクが実行できる状態になる場合は,レディキューにつなぐ.
00075  *  また,ディスパッチが必要な場合には TRUE を返す.
00076  */
00077 Inline BOOL
00078 make_non_wait(TCB *tcb)
00079 {
00080         assert(TSTAT_WAITING(tcb->tstat));
00081 
00082         if (!(TSTAT_SUSPENDED(tcb->tstat))) {
00083                 /*
00084                  *  待ち状態から実行できる状態への遷移
00085                  */
00086                 return(make_runnable(tcb));
00087         }
00088         else {
00089                 /*
00090                  *  二重待ち状態から強制待ち状態への遷移
00091                  */
00092                 tcb->tstat = TS_SUSPENDED;
00093                 LOG_TSKSTAT(tcb);
00094                 return(FALSE);
00095         }
00096 }
00097 
00098 /*
00099  *  待ち解除
00100  */
00101 #ifdef __waicmp
00102 
00103 BOOL
00104 wait_complete(TCB *tcb)
00105 {
00106         if (tcb->winfo->tmevtb != NULL) {
00107                 tmevtb_dequeue(tcb->winfo->tmevtb);
00108         }
00109         tcb->winfo->wercd = E_OK;
00110         return(make_non_wait(tcb));
00111 }
00112 
00113 #endif /* __waicmp */
00114 
00115 /*
00116  *  タイムアウトに伴う待ち解除
00117  */
00118 #ifdef __waitmo
00119 
00120 void
00121 wait_tmout(TCB *tcb)
00122 {
00123         if ((tcb->tstat & TS_WAIT_WOBJ) != 0) {
00124                 queue_delete(&(tcb->task_queue));
00125         }
00126         tcb->winfo->wercd = E_TMOUT;
00127         if (make_non_wait(tcb)) {
00128                 reqflg = TRUE;
00129         }
00130 }
00131 
00132 #endif /* __waitmo */
00133 #ifdef __waitmook
00134 
00135 void
00136 wait_tmout_ok(TCB *tcb)
00137 {
00138         tcb->winfo->wercd = E_OK;
00139         if (make_non_wait(tcb)) {
00140                 reqflg = TRUE;
00141         }
00142 }
00143 
00144 #endif /* __waitmook */
00145 
00146 /*
00147  *  待ち状態の強制解除
00148  */
00149 #ifdef __waican
00150 
00151 void
00152 wait_cancel(TCB *tcb)
00153 {
00154         if (tcb->winfo->tmevtb != NULL) {
00155                 tmevtb_dequeue(tcb->winfo->tmevtb);
00156         }
00157         if ((tcb->tstat & TS_WAIT_WOBJ) != 0) {
00158                 queue_delete(&(tcb->task_queue));
00159         }
00160 }
00161 
00162 #endif /* __waican */
00163 #ifdef __wairel
00164 
00165 BOOL
00166 wait_release(TCB *tcb)
00167 {
00168         wait_cancel(tcb);
00169         tcb->winfo->wercd = E_RLWAI;
00170         return(make_non_wait(tcb));
00171 }
00172 
00173 #endif /* __wairel */
00174 
00175 /*
00176  *  タスクの優先度順の待ちキューへの挿入
00177  */
00178 Inline void
00179 queue_insert_tpri(TCB *tcb, QUEUE *queue)
00180 {
00181         QUEUE   *entry;
00182         UINT    priority = tcb->priority;
00183 
00184         for (entry = queue->next; entry != queue; entry = entry->next) {
00185                 if (priority < ((TCB *) entry)->priority) {
00186                         break;
00187                 }
00188         }
00189         queue_insert_prev(entry, &(tcb->task_queue));
00190 }
00191 
00192 /*
00193  *  実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入
00194  */
00195 Inline void
00196 wobj_queue_insert(WOBJCB *wobjcb)
00197 {
00198         if ((wobjcb->wobjinib->wobjatr & TA_TPRI) != 0) {
00199                 queue_insert_tpri(runtsk, &(wobjcb->wait_queue));
00200         }
00201         else {
00202                 queue_insert_prev(&(wobjcb->wait_queue),
00203                                         &(runtsk->task_queue));
00204         }
00205 }
00206 
00207 /*
00208  *  同期・通信オブジェクトに対する待ち状態への移行
00209  */
00210 #ifdef __wobjwai
00211 
00212 void
00213 wobj_make_wait(WOBJCB *wobjcb, WINFO_WOBJ *winfo)
00214 {
00215         runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ | TS_WAIT_WOBJCB);
00216         make_wait(&(winfo->winfo));
00217         wobj_queue_insert(wobjcb);
00218         winfo->wobjcb = wobjcb;
00219         LOG_TSKSTAT(runtsk);
00220 }
00221 
00222 #endif /* __wobjwai */
00223 #ifdef __wobjwaitmo
00224 
00225 void
00226 wobj_make_wait_tmout(WOBJCB *wobjcb, WINFO_WOBJ *winfo,
00227                                         TMEVTB *tmevtb, TMO tmout)
00228 {
00229         runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ | TS_WAIT_WOBJCB);
00230         make_wait_tmout(&(winfo->winfo), tmevtb, tmout);
00231         wobj_queue_insert(wobjcb);
00232         winfo->wobjcb = wobjcb;
00233         LOG_TSKSTAT(runtsk);
00234 }
00235 
00236 #endif /* __wobjwaitmo */
00237 /*
00238  *  タスクの優先度変更時の処理
00239  */
00240 #ifdef __wobjpri
00241 
00242 void
00243 wobj_change_priority(WOBJCB *wobjcb, TCB *tcb)
00244 {
00245         if ((wobjcb->wobjinib->wobjatr & TA_TPRI) != 0) {
00246                 queue_delete(&(tcb->task_queue));
00247                 queue_insert_tpri(tcb, &(wobjcb->wait_queue));
00248         }
00249 }
00250 
00251 #endif /* __wobjpri */
00252 
00270 /*
00271 @fn         BOOL make_non_wait(TCB *tcb)
00272 @brief      待ち解除のためのタスク状態の更新
00273 @param[in,out] tcb   タスク管理ブロック
00274 @retval     TRUE     ディスパッチが必要
00275 @retval     FALSE    ディスパッチは不要
00276 @ingroup    D1_wait
00277 
00278 tcb で指定されるタスクを,待ち解除するようタスク状態を更新する.待解除するタスクが実行できる状態になる場合は,レディキューにつなぐ.
00279 また,ディスパッチが必要な場合には TRUE を返す.
00280 */
00281 

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