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: task_sync.c 748 2008-03-07 17:18:06Z hiro $ 00041 */ 00042 00043 /* 00044 * タスク付属同期機能 00045 */ 00046 00047 #include "kernel_impl.h" 00048 #include "check.h" 00049 #include "task.h" 00050 #include "wait.h" 00051 00052 /* 00053 * トレースログマクロのデフォルト定義 00054 */ 00055 #ifndef LOG_SLP_TSK_ENTER 00056 #define LOG_SLP_TSK_ENTER() 00057 #endif /* LOG_SLP_TSK_ENTER */ 00058 00059 #ifndef LOG_SLP_TSK_LEAVE 00060 #define LOG_SLP_TSK_LEAVE(ercd) 00061 #endif /* LOG_SLP_TSK_LEAVE */ 00062 00063 #ifndef LOG_TSLP_TSK_ENTER 00064 #define LOG_TSLP_TSK_ENTER(tmout) 00065 #endif /* LOG_TSLP_TSK_ENTER */ 00066 00067 #ifndef LOG_TSLP_TSK_LEAVE 00068 #define LOG_TSLP_TSK_LEAVE(ercd) 00069 #endif /* LOG_TSLP_TSK_LEAVE */ 00070 00071 #ifndef LOG_WUP_TSK_ENTER 00072 #define LOG_WUP_TSK_ENTER(tskid) 00073 #endif /* LOG_WUP_TSK_ENTER */ 00074 00075 #ifndef LOG_WUP_TSK_LEAVE 00076 #define LOG_WUP_TSK_LEAVE(ercd) 00077 #endif /* LOG_WUP_TSK_LEAVE */ 00078 00079 #ifndef LOG_IWUP_TSK_ENTER 00080 #define LOG_IWUP_TSK_ENTER(tskid) 00081 #endif /* LOG_IWUP_TSK_ENTER */ 00082 00083 #ifndef LOG_IWUP_TSK_LEAVE 00084 #define LOG_IWUP_TSK_LEAVE(ercd) 00085 #endif /* LOG_IWUP_TSK_LEAVE */ 00086 00087 #ifndef LOG_CAN_WUP_ENTER 00088 #define LOG_CAN_WUP_ENTER(tskid) 00089 #endif /* LOG_CAN_WUP_ENTER */ 00090 00091 #ifndef LOG_CAN_WUP_LEAVE 00092 #define LOG_CAN_WUP_LEAVE(ercd) 00093 #endif /* LOG_CAN_WUP_LEAVE */ 00094 00095 #ifndef LOG_REL_WAI_ENTER 00096 #define LOG_REL_WAI_ENTER(tskid) 00097 #endif /* LOG_REL_WAI_ENTER */ 00098 00099 #ifndef LOG_REL_WAI_LEAVE 00100 #define LOG_REL_WAI_LEAVE(ercd) 00101 #endif /* LOG_REL_WAI_LEAVE */ 00102 00103 #ifndef LOG_IREL_WAI_ENTER 00104 #define LOG_IREL_WAI_ENTER(tskid) 00105 #endif /* LOG_IREL_WAI_ENTER */ 00106 00107 #ifndef LOG_IREL_WAI_LEAVE 00108 #define LOG_IREL_WAI_LEAVE(ercd) 00109 #endif /* LOG_IREL_WAI_LEAVE */ 00110 00111 #ifndef LOG_SUS_TSK_ENTER 00112 #define LOG_SUS_TSK_ENTER(tskid) 00113 #endif /* LOG_SUS_TSK_ENTER */ 00114 00115 #ifndef LOG_SUS_TSK_LEAVE 00116 #define LOG_SUS_TSK_LEAVE(ercd) 00117 #endif /* LOG_SUS_TSK_LEAVE */ 00118 00119 #ifndef LOG_RSM_TSK_ENTER 00120 #define LOG_RSM_TSK_ENTER(tskid) 00121 #endif /* LOG_RSM_TSK_ENTER */ 00122 00123 #ifndef LOG_RSM_TSK_LEAVE 00124 #define LOG_RSM_TSK_LEAVE(ercd) 00125 #endif /* LOG_RSM_TSK_LEAVE */ 00126 00127 #ifndef LOG_DLY_TSK_ENTER 00128 #define LOG_DLY_TSK_ENTER(dlytim) 00129 #endif /* LOG_DLY_TSK_ENTER */ 00130 00131 #ifndef LOG_DLY_TSK_LEAVE 00132 #define LOG_DLY_TSK_LEAVE(ercd) 00133 #endif /* LOG_DLY_TSK_LEAVE */ 00134 00135 /* 00136 * 起床待ち 00137 */ 00138 #ifdef TOPPERS_slp_tsk 00139 00140 ER 00141 slp_tsk(void) 00142 { 00143 WINFO winfo; 00144 ER ercd; 00145 00146 LOG_SLP_TSK_ENTER(); 00147 CHECK_DISPATCH(); 00148 00149 t_lock_cpu(); 00150 if (p_runtsk->wupque) { 00151 p_runtsk->wupque = false; 00152 ercd = E_OK; 00153 } 00154 else { 00155 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP); 00156 make_wait(&winfo); 00157 LOG_TSKSTAT(p_runtsk); 00158 dispatch(); 00159 ercd = winfo.wercd; 00160 } 00161 t_unlock_cpu(); 00162 00163 error_exit: 00164 LOG_SLP_TSK_LEAVE(ercd); 00165 return(ercd); 00166 } 00167 00168 #endif /* TOPPERS_slp_tsk */ 00169 00170 /* 00171 * 起床待ち(タイムアウトあり) 00172 */ 00173 #ifdef TOPPERS_tslp_tsk 00174 00175 ER 00176 tslp_tsk(TMO tmout) 00177 { 00178 WINFO winfo; 00179 TMEVTB tmevtb; 00180 ER ercd; 00181 00182 LOG_TSLP_TSK_ENTER(tmout); 00183 CHECK_DISPATCH(); 00184 CHECK_TMOUT(tmout); 00185 00186 t_lock_cpu(); 00187 if (p_runtsk->wupque) { 00188 p_runtsk->wupque = false; 00189 ercd = E_OK; 00190 } 00191 else if (tmout == TMO_POL) { 00192 ercd = E_TMOUT; 00193 } 00194 else { 00195 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP); 00196 make_wait_tmout(&winfo, &tmevtb, tmout); 00197 LOG_TSKSTAT(p_runtsk); 00198 dispatch(); 00199 ercd = winfo.wercd; 00200 } 00201 t_unlock_cpu(); 00202 00203 error_exit: 00204 LOG_TSLP_TSK_LEAVE(ercd); 00205 return(ercd); 00206 } 00207 00208 #endif /* TOPPERS_tslp_tsk */ 00209 00210 /* 00211 * タスクの起床 00212 */ 00213 #ifdef TOPPERS_wup_tsk 00214 00215 ER 00216 wup_tsk(ID tskid) 00217 { 00218 TCB *p_tcb; 00219 ER ercd; 00220 00221 LOG_WUP_TSK_ENTER(tskid); 00222 CHECK_TSKCTX_UNL(); 00223 CHECK_TSKID_SELF(tskid); 00224 p_tcb = get_tcb_self(tskid); 00225 00226 t_lock_cpu(); 00227 if (TSTAT_DORMANT(p_tcb->tstat)) { 00228 ercd = E_OBJ; 00229 } 00230 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) { 00231 if (wait_complete(p_tcb)) { 00232 dispatch(); 00233 } 00234 ercd = E_OK; 00235 } 00236 else if (!(p_tcb->wupque)) { 00237 p_tcb->wupque = true; 00238 ercd = E_OK; 00239 } 00240 else { 00241 ercd = E_QOVR; 00242 } 00243 t_unlock_cpu(); 00244 00245 error_exit: 00246 LOG_WUP_TSK_LEAVE(ercd); 00247 return(ercd); 00248 } 00249 00250 #endif /* TOPPERS_wup_tsk */ 00251 00252 /* 00253 * タスクの起床(非タスクコンテキスト用) 00254 */ 00255 #ifdef TOPPERS_iwup_tsk 00256 00257 ER 00258 iwup_tsk(ID tskid) 00259 { 00260 TCB *p_tcb; 00261 ER ercd; 00262 00263 LOG_IWUP_TSK_ENTER(tskid); 00264 CHECK_INTCTX_UNL(); 00265 CHECK_TSKID(tskid); 00266 p_tcb = get_tcb(tskid); 00267 00268 i_lock_cpu(); 00269 if (TSTAT_DORMANT(p_tcb->tstat)) { 00270 ercd = E_OBJ; 00271 } 00272 else if (TSTAT_WAIT_SLP(p_tcb->tstat)) { 00273 if (wait_complete(p_tcb)) { 00274 reqflg = true; 00275 } 00276 ercd = E_OK; 00277 } 00278 else if (!(p_tcb->wupque)) { 00279 p_tcb->wupque = true; 00280 ercd = E_OK; 00281 } 00282 else { 00283 ercd = E_QOVR; 00284 } 00285 i_unlock_cpu(); 00286 00287 error_exit: 00288 LOG_IWUP_TSK_LEAVE(ercd); 00289 return(ercd); 00290 } 00291 00292 #endif /* TOPPERS_iwup_tsk */ 00293 00294 /* 00295 * タスク起床要求のキャンセル 00296 */ 00297 #ifdef TOPPERS_can_wup 00298 00299 ER_UINT 00300 can_wup(ID tskid) 00301 { 00302 TCB *p_tcb; 00303 ER_UINT ercd; 00304 00305 LOG_CAN_WUP_ENTER(tskid); 00306 CHECK_TSKCTX_UNL(); 00307 CHECK_TSKID_SELF(tskid); 00308 p_tcb = get_tcb_self(tskid); 00309 00310 t_lock_cpu(); 00311 if (TSTAT_DORMANT(p_tcb->tstat)) { 00312 ercd = E_OBJ; 00313 } 00314 else { 00315 ercd = p_tcb->wupque ? 1 : 0; 00316 p_tcb->wupque = false; 00317 } 00318 t_unlock_cpu(); 00319 00320 error_exit: 00321 LOG_CAN_WUP_LEAVE(ercd); 00322 return(ercd); 00323 } 00324 00325 #endif /* TOPPERS_can_wup */ 00326 00327 /* 00328 * 待ち状態の強制解除 00329 */ 00330 #ifdef TOPPERS_rel_wai 00331 00332 ER 00333 rel_wai(ID tskid) 00334 { 00335 TCB *p_tcb; 00336 ER ercd; 00337 00338 LOG_REL_WAI_ENTER(tskid); 00339 CHECK_TSKCTX_UNL(); 00340 CHECK_TSKID(tskid); 00341 p_tcb = get_tcb(tskid); 00342 00343 t_lock_cpu(); 00344 if (!TSTAT_WAITING(p_tcb->tstat)) { 00345 ercd = E_OBJ; 00346 } 00347 else { 00348 if (wait_release(p_tcb)) { 00349 dispatch(); 00350 } 00351 ercd = E_OK; 00352 } 00353 t_unlock_cpu(); 00354 00355 error_exit: 00356 LOG_REL_WAI_LEAVE(ercd); 00357 return(ercd); 00358 } 00359 00360 #endif /* TOPPERS_rel_wai */ 00361 00362 /* 00363 * 待ち状態の強制解除(非タスクコンテキスト用) 00364 */ 00365 #ifdef TOPPERS_irel_wai 00366 00367 ER 00368 irel_wai(ID tskid) 00369 { 00370 TCB *p_tcb; 00371 ER ercd; 00372 00373 LOG_IREL_WAI_ENTER(tskid); 00374 CHECK_INTCTX_UNL(); 00375 CHECK_TSKID(tskid); 00376 p_tcb = get_tcb(tskid); 00377 00378 i_lock_cpu(); 00379 if (!TSTAT_WAITING(p_tcb->tstat)) { 00380 ercd = E_OBJ; 00381 } 00382 else { 00383 if (wait_release(p_tcb)) { 00384 reqflg = true; 00385 } 00386 ercd = E_OK; 00387 } 00388 i_unlock_cpu(); 00389 00390 error_exit: 00391 LOG_IREL_WAI_LEAVE(ercd); 00392 return(ercd); 00393 } 00394 00395 #endif /* TOPPERS_irel_wai */ 00396 00397 /* 00398 * 強制待ち状態への移行 00399 */ 00400 #ifdef TOPPERS_sus_tsk 00401 00402 ER 00403 sus_tsk(ID tskid) 00404 { 00405 TCB *p_tcb; 00406 ER ercd; 00407 00408 LOG_SUS_TSK_ENTER(tskid); 00409 CHECK_TSKCTX_UNL(); 00410 CHECK_TSKID_SELF(tskid); 00411 p_tcb = get_tcb_self(tskid); 00412 00413 t_lock_cpu(); 00414 if (p_tcb == p_runtsk && !dspflg) { 00415 ercd = E_CTX; 00416 } 00417 else if (TSTAT_DORMANT(p_tcb->tstat)) { 00418 ercd = E_OBJ; 00419 } 00420 else if (TSTAT_RUNNABLE(p_tcb->tstat)) { 00421 /* 00422 * 実行できる状態から強制待ち状態への遷移 00423 */ 00424 p_tcb->tstat = TS_SUSPENDED; 00425 LOG_TSKSTAT(p_tcb); 00426 if (make_non_runnable(p_tcb)) { 00427 dispatch(); 00428 } 00429 ercd = E_OK; 00430 } 00431 else if (TSTAT_SUSPENDED(p_tcb->tstat)) { 00432 ercd = E_QOVR; 00433 } 00434 else { 00435 /* 00436 * 待ち状態から二重待ち状態への遷移 00437 */ 00438 p_tcb->tstat |= TS_SUSPENDED; 00439 LOG_TSKSTAT(p_tcb); 00440 ercd = E_OK; 00441 } 00442 t_unlock_cpu(); 00443 00444 error_exit: 00445 LOG_SUS_TSK_LEAVE(ercd); 00446 return(ercd); 00447 } 00448 00449 #endif /* TOPPERS_sus_tsk */ 00450 00451 /* 00452 * 強制待ち状態からの再開 00453 */ 00454 #ifdef TOPPERS_rsm_tsk 00455 00456 ER 00457 rsm_tsk(ID tskid) 00458 { 00459 TCB *p_tcb; 00460 ER ercd; 00461 00462 LOG_RSM_TSK_ENTER(tskid); 00463 CHECK_TSKCTX_UNL(); 00464 CHECK_TSKID(tskid); 00465 p_tcb = get_tcb(tskid); 00466 00467 t_lock_cpu(); 00468 if (!TSTAT_SUSPENDED(p_tcb->tstat)) { 00469 ercd = E_OBJ; 00470 } 00471 else if (!TSTAT_WAITING(p_tcb->tstat)) { 00472 /* 00473 * 強制待ち状態から実行できる状態への遷移 00474 */ 00475 if (make_runnable(p_tcb)) { 00476 dispatch(); 00477 } 00478 ercd = E_OK; 00479 } 00480 else { 00481 /* 00482 * 二重待ち状態から待ち状態への遷移 00483 */ 00484 p_tcb->tstat &= ~TS_SUSPENDED; 00485 LOG_TSKSTAT(p_tcb); 00486 ercd = E_OK; 00487 } 00488 t_unlock_cpu(); 00489 00490 error_exit: 00491 LOG_RSM_TSK_LEAVE(ercd); 00492 return(ercd); 00493 } 00494 00495 #endif /* TOPPERS_rsm_tsk */ 00496 00497 /* 00498 * 自タスクの遅延 00499 */ 00500 #ifdef TOPPERS_dly_tsk 00501 00502 ER 00503 dly_tsk(RELTIM dlytim) 00504 { 00505 WINFO winfo; 00506 TMEVTB tmevtb; 00507 ER ercd; 00508 00509 LOG_DLY_TSK_ENTER(dlytim); 00510 CHECK_DISPATCH(); 00511 CHECK_PAR(dlytim <= TMAX_RELTIM); 00512 00513 t_lock_cpu(); 00514 p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY); 00515 (void) make_non_runnable(p_runtsk); 00516 p_runtsk->p_winfo = &winfo; 00517 winfo.p_tmevtb = &tmevtb; 00518 tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk); 00519 LOG_TSKSTAT(p_runtsk); 00520 dispatch(); 00521 ercd = winfo.wercd; 00522 t_unlock_cpu(); 00523 00524 error_exit: 00525 LOG_DLY_TSK_LEAVE(ercd); 00526 return(ercd); 00527 } 00528 00529 #endif /* TOPPERS_dly_tsk */
Copyright © 2008 by Kijineko Inc.