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.