|
|
task_sync.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: task_sync.c,v 1.7 2003/12/20 08:12:24 hiro Exp $ 00037 */ 00038 00039 /* 00040 * タスク付属同期機能 00041 */ 00042 00043 #include "jsp_kernel.h" 00044 #include "check.h" 00045 #include "task.h" 00046 #include "wait.h" 00047 00048 /* 00049 * 起床待ち 00050 */ 00051 #ifdef __slp_tsk 00052 00053 SYSCALL ER 00054 slp_tsk() 00055 { 00056 WINFO winfo; 00057 ER ercd; 00058 00059 LOG_SLP_TSK_ENTER(); 00060 CHECK_DISPATCH(); 00061 00062 t_lock_cpu(); 00063 if (runtsk->wupcnt) { 00064 runtsk->wupcnt = FALSE; 00065 ercd = E_OK; 00066 } 00067 else { 00068 runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP); 00069 make_wait(&winfo); 00070 LOG_TSKSTAT(runtsk); 00071 dispatch(); 00072 ercd = winfo.wercd; 00073 } 00074 t_unlock_cpu(); 00075 00076 exit: 00077 LOG_SLP_TSK_LEAVE(ercd); 00078 return(ercd); 00079 } 00080 00081 #endif /* __slp_tsk */ 00082 00083 /* 00084 * 起床待ち(タイムアウトあり) 00085 */ 00086 #ifdef __tslp_tsk 00087 00088 SYSCALL ER 00089 tslp_tsk(TMO tmout) 00090 { 00091 WINFO winfo; 00092 TMEVTB tmevtb; 00093 ER ercd; 00094 00095 LOG_TSLP_TSK_ENTER(tmout); 00096 CHECK_DISPATCH(); 00097 CHECK_TMOUT(tmout); 00098 00099 t_lock_cpu(); 00100 if (runtsk->wupcnt) { 00101 runtsk->wupcnt = FALSE; 00102 ercd = E_OK; 00103 } 00104 else if (tmout == TMO_POL) { 00105 ercd = E_TMOUT; 00106 } 00107 else { 00108 runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP); 00109 make_wait_tmout(&winfo, &tmevtb, tmout); 00110 LOG_TSKSTAT(runtsk); 00111 dispatch(); 00112 ercd = winfo.wercd; 00113 } 00114 t_unlock_cpu(); 00115 00116 exit: 00117 LOG_TSLP_TSK_LEAVE(ercd); 00118 return(ercd); 00119 } 00120 00121 #endif /* __tslp_tsk */ 00122 00123 /* 00124 * タスクの起床 00125 */ 00126 #ifdef __wup_tsk 00127 00128 SYSCALL ER 00129 wup_tsk(ID tskid) 00130 { 00131 TCB *tcb; 00132 UINT tstat; 00133 ER ercd; 00134 00135 LOG_WUP_TSK_ENTER(tskid); 00136 CHECK_TSKCTX_UNL(); 00137 CHECK_TSKID_SELF(tskid); 00138 tcb = get_tcb_self(tskid); 00139 00140 t_lock_cpu(); 00141 if (TSTAT_DORMANT(tstat = tcb->tstat)) { 00142 ercd = E_OBJ; 00143 } 00144 else if ((tstat & TS_WAIT_SLEEP) != 0) { 00145 if (wait_complete(tcb)) { 00146 dispatch(); 00147 } 00148 ercd = E_OK; 00149 } 00150 else if (!(tcb->wupcnt)) { 00151 tcb->wupcnt = TRUE; 00152 ercd = E_OK; 00153 } 00154 else { 00155 ercd = E_QOVR; 00156 } 00157 t_unlock_cpu(); 00158 00159 exit: 00160 LOG_WUP_TSK_LEAVE(ercd); 00161 return(ercd); 00162 } 00163 00164 #endif /* __wup_tsk */ 00165 00166 /* 00167 * タスクの起床(非タスクコンテキスト用) 00168 */ 00169 #ifdef __iwup_tsk 00170 00171 SYSCALL ER 00172 iwup_tsk(ID tskid) 00173 { 00174 TCB *tcb; 00175 UINT tstat; 00176 ER ercd; 00177 00178 LOG_IWUP_TSK_ENTER(tskid); 00179 CHECK_INTCTX_UNL(); 00180 CHECK_TSKID(tskid); 00181 tcb = get_tcb(tskid); 00182 00183 i_lock_cpu(); 00184 if (TSTAT_DORMANT(tstat = tcb->tstat)) { 00185 ercd = E_OBJ; 00186 } 00187 else if ((tstat & TS_WAIT_SLEEP) != 0) { 00188 if (wait_complete(tcb)) { 00189 reqflg = TRUE; 00190 } 00191 ercd = E_OK; 00192 } 00193 else if (!(tcb->wupcnt)) { 00194 tcb->wupcnt = TRUE; 00195 ercd = E_OK; 00196 } 00197 else { 00198 ercd = E_QOVR; 00199 } 00200 i_unlock_cpu(); 00201 00202 exit: 00203 LOG_IWUP_TSK_LEAVE(ercd); 00204 return(ercd); 00205 } 00206 00207 #endif /* __iwup_tsk */ 00208 00209 /* 00210 * タスク起床要求のキャンセル 00211 */ 00212 #ifdef __can_wup 00213 00214 SYSCALL ER_UINT 00215 can_wup(ID tskid) 00216 { 00217 TCB *tcb; 00218 ER_UINT ercd; 00219 00220 LOG_CAN_WUP_ENTER(tskid); 00221 CHECK_TSKCTX_UNL(); 00222 CHECK_TSKID_SELF(tskid); 00223 tcb = get_tcb_self(tskid); 00224 00225 t_lock_cpu(); 00226 if (TSTAT_DORMANT(tcb->tstat)) { 00227 ercd = E_OBJ; 00228 } 00229 else { 00230 ercd = tcb->wupcnt ? 1 : 0; 00231 tcb->wupcnt = FALSE; 00232 } 00233 t_unlock_cpu(); 00234 00235 exit: 00236 LOG_CAN_WUP_LEAVE(ercd); 00237 return(ercd); 00238 } 00239 00240 #endif /* __can_wup */ 00241 00242 /* 00243 * 待ち状態の強制解除 00244 */ 00245 #ifdef __rel_wai 00246 00247 SYSCALL ER 00248 rel_wai(ID tskid) 00249 { 00250 TCB *tcb; 00251 ER ercd; 00252 00253 LOG_REL_WAI_ENTER(tskid); 00254 CHECK_TSKCTX_UNL(); 00255 CHECK_TSKID(tskid); 00256 tcb = get_tcb(tskid); 00257 00258 t_lock_cpu(); 00259 if (!(TSTAT_WAITING(tcb->tstat))) { 00260 ercd = E_OBJ; 00261 } 00262 else { 00263 if (wait_release(tcb)) { 00264 dispatch(); 00265 } 00266 ercd = E_OK; 00267 } 00268 t_unlock_cpu(); 00269 00270 exit: 00271 LOG_REL_WAI_LEAVE(ercd); 00272 return(ercd); 00273 } 00274 00275 #endif /* __rel_wai */ 00276 00277 /* 00278 * 待ち状態の強制解除(非タスクコンテキスト用) 00279 */ 00280 #ifdef __irel_wai 00281 00282 SYSCALL ER 00283 irel_wai(ID tskid) 00284 { 00285 TCB *tcb; 00286 ER ercd; 00287 00288 LOG_IREL_WAI_ENTER(tskid); 00289 CHECK_INTCTX_UNL(); 00290 CHECK_TSKID(tskid); 00291 tcb = get_tcb(tskid); 00292 00293 i_lock_cpu(); 00294 if (!(TSTAT_WAITING(tcb->tstat))) { 00295 ercd = E_OBJ; 00296 } 00297 else { 00298 if (wait_release(tcb)) { 00299 reqflg = TRUE; 00300 } 00301 ercd = E_OK; 00302 } 00303 i_unlock_cpu(); 00304 00305 exit: 00306 LOG_IREL_WAI_LEAVE(ercd); 00307 return(ercd); 00308 } 00309 00310 #endif /* __irel_wai */ 00311 00312 /* 00313 * 強制待ち状態への移行 00314 */ 00315 #ifdef __sus_tsk 00316 00317 SYSCALL ER 00318 sus_tsk(ID tskid) 00319 { 00320 TCB *tcb; 00321 UINT tstat; 00322 ER ercd; 00323 00324 LOG_SUS_TSK_ENTER(tskid); 00325 CHECK_TSKCTX_UNL(); 00326 CHECK_TSKID_SELF(tskid); 00327 tcb = get_tcb_self(tskid); 00328 00329 t_lock_cpu(); 00330 if (tcb == runtsk && !(enadsp)) { 00331 ercd = E_CTX; 00332 } 00333 else if (TSTAT_DORMANT(tstat = tcb->tstat)) { 00334 ercd = E_OBJ; 00335 } 00336 else if (TSTAT_RUNNABLE(tstat)) { 00337 /* 00338 * 実行できる状態から強制待ち状態への遷移 00339 */ 00340 tcb->tstat = TS_SUSPENDED; 00341 LOG_TSKSTAT(tcb); 00342 if (make_non_runnable(tcb)) { 00343 dispatch(); 00344 } 00345 ercd = E_OK; 00346 } 00347 else if (TSTAT_SUSPENDED(tstat)) { 00348 ercd = E_QOVR; 00349 } 00350 else { 00351 /* 00352 * 待ち状態から二重待ち状態への遷移 00353 */ 00354 tcb->tstat |= TS_SUSPENDED; 00355 LOG_TSKSTAT(tcb); 00356 ercd = E_OK; 00357 } 00358 t_unlock_cpu(); 00359 00360 exit: 00361 LOG_SUS_TSK_LEAVE(ercd); 00362 return(ercd); 00363 } 00364 00365 #endif /* __sus_tsk */ 00366 00367 /* 00368 * 強制待ち状態からの再開 00369 */ 00370 #ifdef __rsm_tsk 00371 00372 SYSCALL ER 00373 rsm_tsk(ID tskid) 00374 { 00375 TCB *tcb; 00376 UINT tstat; 00377 ER ercd; 00378 00379 LOG_RSM_TSK_ENTER(tskid); 00380 CHECK_TSKCTX_UNL(); 00381 CHECK_TSKID(tskid); 00382 tcb = get_tcb(tskid); 00383 00384 t_lock_cpu(); 00385 if (!(TSTAT_SUSPENDED(tstat = tcb->tstat))) { 00386 ercd = E_OBJ; 00387 } 00388 else if (!(TSTAT_WAITING(tstat))) { 00389 /* 00390 * 強制待ち状態から実行できる状態への遷移 00391 */ 00392 if (make_runnable(tcb)) { 00393 dispatch(); 00394 } 00395 ercd = E_OK; 00396 } 00397 else { 00398 /* 00399 * 二重待ち状態から待ち状態への遷移 00400 */ 00401 tcb->tstat &= ~TS_SUSPENDED; 00402 LOG_TSKSTAT(tcb); 00403 ercd = E_OK; 00404 } 00405 t_unlock_cpu(); 00406 00407 exit: 00408 LOG_RSM_TSK_LEAVE(ercd); 00409 return(ercd); 00410 } 00411 00412 #endif /* __rsm_tsk */ 00413 00414 /* 00415 * 強制待ち状態からの強制再開 00416 * 00417 * JSPカーネルでは,frsm_tsk と rsm_tsk は同一の処理となる.frsm_tsk 00418 * が呼ばれると,frsm_tsk と rsm_tsk の両方のサービスコールのトレース 00419 * ログが出力される.ログ取得後に rsm_tsk のトレースログを削除するこ 00420 * とが必要である.rsm_tsk のトレースログを正しく削除するためには,タ 00421 * スクディスパッチのログと,タスク例外処理のログも取得することが必要 00422 * となるので,注意が必要である. 00423 */ 00424 #ifdef __frsm_tsk 00425 00426 SYSCALL ER 00427 frsm_tsk(ID tskid) 00428 { 00429 ER ercd; 00430 00431 LOG_FRSM_TSK_ENTER(tskid); 00432 ercd = rsm_tsk(tskid); 00433 LOG_FRSM_TSK_LEAVE(ercd); 00434 return(ercd); 00435 } 00436 00437 #endif /* __frsm_tsk */ 00438 00439 /* 00440 * 自タスクの遅延 00441 */ 00442 #ifdef __dly_tsk 00443 00444 SYSCALL ER 00445 dly_tsk(RELTIM dlytim) 00446 { 00447 WINFO winfo; 00448 TMEVTB tmevtb; 00449 ER ercd; 00450 00451 LOG_DLY_TSK_ENTER(dlytim); 00452 CHECK_DISPATCH(); 00453 CHECK_PAR(dlytim <= TMAX_RELTIM); 00454 00455 t_lock_cpu(); 00456 runtsk->tstat = TS_WAITING; 00457 make_non_runnable(runtsk); 00458 runtsk->winfo = &winfo; 00459 winfo.tmevtb = &tmevtb; 00460 tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (VP) runtsk); 00461 LOG_TSKSTAT(runtsk); 00462 dispatch(); 00463 ercd = winfo.wercd; 00464 t_unlock_cpu(); 00465 00466 exit: 00467 LOG_DLY_TSK_LEAVE(ercd); 00468 return(ercd); 00469 } 00470 00471 #endif /* __dly_tsk */ 00472 Copyright © 2006 by TAKAGI Nobuhisa. Copyright © 2006 by Kijineko Inc.. このページは Mon Dec 18 17:18:41 2006 に Doxygen によって生成されました。 データ入力からプログラム開発まで!様々なスキルを持ったメンバーが登録しています【@SOHO】 |