wait.c

説明を見る。
00001 /*
00002  *  TOPPERS/ASP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Advanced Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  *  Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
00009  *              Graduate School of Information Science, Nagoya Univ., JAPAN
00010  * 
00011  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
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  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
00032  *      免責すること.
00033  * 
00034  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00035  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
00036  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
00037  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
00038  *  の責任を負わない.
00039  * 
00040  *  @(#) $Id: wait.c 748 2008-03-07 17:18:06Z hiro $
00041  */
00042 
00043 /*
00044  *      待ち状態管理モジュール
00045  */
00046 
00047 #include "kernel_impl.h"
00048 #include "wait.h"
00049 
00050 /*
00051  *  待ち状態への移行(タイムアウト指定)
00052  */
00053 #ifdef TOPPERS_waimake
00054 
00055 void
00056 make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout)
00057 {
00058     (void) make_non_runnable(p_runtsk);
00059     p_runtsk->p_winfo = p_winfo;
00060     if (tmout > 0) {
00061         p_winfo->p_tmevtb = p_tmevtb;
00062         tmevtb_enqueue(p_tmevtb, (RELTIM) tmout,
00063                         (CBACK) wait_tmout, (void *) p_runtsk);
00064     }
00065     else {
00066         assert(tmout == TMO_FEVR);
00067         p_winfo->p_tmevtb = NULL;
00068     }
00069 }
00070 
00071 #endif /* TOPPERS_waimake */
00072 
00073 /*
00074  *  待ち解除のためのタスク状態の更新
00075  *
00076  *  p_tcbで指定されるタスクを,待ち解除するようタスク状態を更新する.
00077  *  待ち解除するタスクが実行できる状態になる場合は,レディキューにつな
00078  *  ぐ.また,ディスパッチが必要な場合にはtrueを返す.
00079  */
00080 Inline bool_t
00081 make_non_wait(TCB *p_tcb)
00082 {
00083     assert(TSTAT_WAITING(p_tcb->tstat));
00084 
00085     if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
00086         /*
00087          *  待ち状態から実行できる状態への遷移
00088          */
00089         return(make_runnable(p_tcb));
00090     }
00091     else {
00092         /*
00093          *  二重待ち状態から強制待ち状態への遷移
00094          */
00095         p_tcb->tstat = TS_SUSPENDED;
00096         LOG_TSKSTAT(p_tcb);
00097         return(false);
00098     }
00099 }
00100 
00101 /*
00102  *  待ち解除
00103  */
00104 #ifdef TOPPERS_waicmp
00105 
00106 bool_t
00107 wait_complete(TCB *p_tcb)
00108 {
00109     wait_dequeue_tmevtb(p_tcb);
00110     p_tcb->p_winfo->wercd = E_OK;
00111     return(make_non_wait(p_tcb));
00112 }
00113 
00114 #endif /* TOPPERS_waicmp */
00115 
00116 /*
00117  *  タイムアウトに伴う待ち解除
00118  */
00119 #ifdef TOPPERS_waitmo
00120 
00121 void
00122 wait_tmout(TCB *p_tcb)
00123 {
00124     wait_dequeue_wobj(p_tcb);
00125     p_tcb->p_winfo->wercd = E_TMOUT;
00126     if (make_non_wait(p_tcb)) {
00127         reqflg = true;
00128     }
00129 
00130     /*
00131      *  ここで優先度の高い割込みを受け付ける.
00132      */
00133     i_unlock_cpu();
00134     i_lock_cpu();
00135 }
00136 
00137 #endif /* TOPPERS_waitmo */
00138 #ifdef TOPPERS_waitmook
00139 
00140 void
00141 wait_tmout_ok(TCB *p_tcb)
00142 {
00143     p_tcb->p_winfo->wercd = E_OK;
00144     if (make_non_wait(p_tcb)) {
00145         reqflg = true;
00146     }
00147 
00148     /*
00149      *  ここで優先度の高い割込みを受け付ける.
00150      */
00151     i_unlock_cpu();
00152     i_lock_cpu();
00153 }
00154 
00155 #endif /* TOPPERS_waitmook */
00156 
00157 /*
00158  *  待ち状態の強制解除
00159  */
00160 #ifdef TOPPERS_wairel
00161 
00162 bool_t
00163 wait_release(TCB *p_tcb)
00164 {
00165     wait_dequeue_wobj(p_tcb);
00166     wait_dequeue_tmevtb(p_tcb);
00167     p_tcb->p_winfo->wercd = E_RLWAI;
00168     return(make_non_wait(p_tcb));
00169 }
00170 
00171 #endif /* TOPPERS_wairel */
00172 
00173 /*
00174  *  実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入
00175  *
00176  *  実行中のタスクを,同期・通信オブジェクトの待ちキューへ挿入する.オ
00177  *  ブジェクトの属性に応じて,FIFO順またはタスク優先度順で挿入する.
00178  */
00179 Inline void
00180 wobj_queue_insert(WOBJCB *p_wobjcb)
00181 {
00182     if ((p_wobjcb->p_wobjinib->wobjatr & TA_TPRI) != 0U) {
00183         queue_insert_tpri(&(p_wobjcb->wait_queue), p_runtsk);
00184     }
00185     else {
00186         queue_insert_prev(&(p_wobjcb->wait_queue), &(p_runtsk->task_queue));
00187     }
00188 }
00189 
00190 /*
00191  *  同期・通信オブジェクトに対する待ち状態への移行
00192  */
00193 #ifdef TOPPERS_wobjwai
00194 
00195 void
00196 wobj_make_wait(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj)
00197 {
00198     make_wait((WINFO *) p_winfo_wobj);
00199     wobj_queue_insert(p_wobjcb);
00200     p_winfo_wobj->p_wobjcb = p_wobjcb;
00201     LOG_TSKSTAT(p_runtsk);
00202 }
00203 
00204 #endif /* TOPPERS_wobjwai */
00205 #ifdef TOPPERS_wobjwaitmo
00206 
00207 void
00208 wobj_make_wait_tmout(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj,
00209                                 TMEVTB *p_tmevtb, TMO tmout)
00210 {
00211     make_wait_tmout((WINFO *) p_winfo_wobj, p_tmevtb, tmout);
00212     wobj_queue_insert(p_wobjcb);
00213     p_winfo_wobj->p_wobjcb = p_wobjcb;
00214     LOG_TSKSTAT(p_runtsk);
00215 }
00216 
00217 #endif /* TOPPERS_wobjwaitmo */
00218 
00219 /*
00220  *  待ちキューの初期化
00221  */
00222 #ifdef TOPPERS_iniwque
00223 
00224 bool_t
00225 init_wait_queue(QUEUE *p_wait_queue)
00226 {
00227     TCB     *p_tcb;
00228     bool_t  dspreq = false;
00229 
00230     while (!queue_empty(p_wait_queue)) {
00231         p_tcb = (TCB *) queue_delete_next(p_wait_queue);
00232         wait_dequeue_tmevtb(p_tcb);
00233         p_tcb->p_winfo->wercd = E_DLT;
00234         if (make_non_wait(p_tcb)) {
00235             dspreq = true;
00236         };
00237     }
00238     return(dspreq);
00239 }
00240 
00241 #endif /* TOPPERS_iniwque */

Copyright © 2008 by Kijineko Inc.

ホームページ制作