|
|
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 によって生成されました。 |