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: eventflag.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 #include "eventflag.h" 00052 00053 /* 00054 * トレースログマクロのデフォルト定義 00055 */ 00056 #ifndef LOG_SET_FLG_ENTER 00057 #define LOG_SET_FLG_ENTER(flgid, setptn) 00058 #endif /* LOG_SET_FLG_ENTER */ 00059 00060 #ifndef LOG_SET_FLG_LEAVE 00061 #define LOG_SET_FLG_LEAVE(ercd) 00062 #endif /* LOG_SET_FLG_LEAVE */ 00063 00064 #ifndef LOG_ISET_FLG_ENTER 00065 #define LOG_ISET_FLG_ENTER(flgid, setptn) 00066 #endif /* LOG_ISET_FLG_ENTER */ 00067 00068 #ifndef LOG_ISET_FLG_LEAVE 00069 #define LOG_ISET_FLG_LEAVE(ercd) 00070 #endif /* LOG_ISET_FLG_LEAVE */ 00071 00072 #ifndef LOG_CLR_FLG_ENTER 00073 #define LOG_CLR_FLG_ENTER(flgid, clrptn) 00074 #endif /* LOG_CLR_FLG_ENTER */ 00075 00076 #ifndef LOG_CLR_FLG_LEAVE 00077 #define LOG_CLR_FLG_LEAVE(ercd) 00078 #endif /* LOG_CLR_FLG_LEAVE */ 00079 00080 #ifndef LOG_WAI_FLG_ENTER 00081 #define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn) 00082 #endif /* LOG_WAI_FLG_ENTER */ 00083 00084 #ifndef LOG_WAI_FLG_LEAVE 00085 #define LOG_WAI_FLG_LEAVE(ercd, flgptn) 00086 #endif /* LOG_WAI_FLG_LEAVE */ 00087 00088 #ifndef LOG_POL_FLG_ENTER 00089 #define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn) 00090 #endif /* LOG_POL_FLG_ENTER */ 00091 00092 #ifndef LOG_POL_FLG_LEAVE 00093 #define LOG_POL_FLG_LEAVE(ercd, flgptn) 00094 #endif /* LOG_POL_FLG_LEAVE */ 00095 00096 #ifndef LOG_TWAI_FLG_ENTER 00097 #define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout) 00098 #endif /* LOG_TWAI_FLG_ENTER */ 00099 00100 #ifndef LOG_TWAI_FLG_LEAVE 00101 #define LOG_TWAI_FLG_LEAVE(ercd, flgptn) 00102 #endif /* LOG_TWAI_FLG_LEAVE */ 00103 00104 #ifndef LOG_INI_FLG_ENTER 00105 #define LOG_INI_FLG_ENTER(flgid) 00106 #endif /* LOG_INI_FLG_ENTER */ 00107 00108 #ifndef LOG_INI_FLG_LEAVE 00109 #define LOG_INI_FLG_LEAVE(ercd) 00110 #endif /* LOG_INI_FLG_LEAVE */ 00111 00112 #ifndef LOG_REF_FLG_ENTER 00113 #define LOG_REF_FLG_ENTER(flgid, pk_rflg) 00114 #endif /* LOG_REF_FLG_ENTER */ 00115 00116 #ifndef LOG_REF_FLG_LEAVE 00117 #define LOG_REF_FLG_LEAVE(ercd, pk_rflg) 00118 #endif /* LOG_REF_FLG_LEAVE */ 00119 00120 /* 00121 * イベントフラグの数 00122 */ 00123 #define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1)) 00124 00125 /* 00126 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ 00127 */ 00128 #define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID)) 00129 #define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)])) 00130 00131 /* 00132 * イベントフラグ機能の初期化 00133 */ 00134 #ifdef TOPPERS_flgini 00135 00136 void 00137 initialize_eventflag(void) 00138 { 00139 uint_t i; 00140 FLGCB *p_flgcb; 00141 00142 for (p_flgcb = flgcb_table, i = 0; i < tnum_flg; p_flgcb++, i++) { 00143 queue_initialize(&(p_flgcb->wait_queue)); 00144 p_flgcb->p_flginib = &(flginib_table[i]); 00145 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn; 00146 } 00147 } 00148 00149 #endif /* TOPPERS_flgini */ 00150 00151 /* 00152 * イベントフラグ待ち解除条件のチェック 00153 */ 00154 #ifdef TOPPERS_flgcnd 00155 00156 bool_t 00157 check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) 00158 { 00159 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U 00160 : (p_flgcb->flgptn & waiptn) == waiptn) { 00161 *p_flgptn = p_flgcb->flgptn; 00162 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) { 00163 p_flgcb->flgptn = 0U; 00164 } 00165 return(true); 00166 } 00167 return(false); 00168 } 00169 00170 #endif /* TOPPERS_flgcnd */ 00171 00172 /* 00173 * イベントフラグのセット 00174 */ 00175 #ifdef TOPPERS_set_flg 00176 00177 ER 00178 set_flg(ID flgid, FLGPTN setptn) 00179 { 00180 FLGCB *p_flgcb; 00181 QUEUE *p_queue; 00182 TCB *p_tcb; 00183 WINFO_FLG *p_winfo_flg; 00184 bool_t dspreq = false; 00185 ER ercd; 00186 00187 LOG_SET_FLG_ENTER(flgid, setptn); 00188 CHECK_TSKCTX_UNL(); 00189 CHECK_FLGID(flgid); 00190 p_flgcb = get_flgcb(flgid); 00191 00192 t_lock_cpu(); 00193 p_flgcb->flgptn |= setptn; 00194 p_queue = p_flgcb->wait_queue.p_next; 00195 while (p_queue != &(p_flgcb->wait_queue)) { 00196 p_tcb = (TCB *) p_queue; 00197 p_queue = p_queue->p_next; 00198 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo); 00199 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn, 00200 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) { 00201 queue_delete(&(p_tcb->task_queue)); 00202 if (wait_complete(p_tcb)) { 00203 dspreq = true; 00204 } 00205 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) { 00206 break; 00207 } 00208 } 00209 } 00210 if (dspreq) { 00211 dispatch(); 00212 } 00213 ercd = E_OK; 00214 t_unlock_cpu(); 00215 00216 error_exit: 00217 LOG_SET_FLG_LEAVE(ercd); 00218 return(ercd); 00219 } 00220 00221 #endif /* TOPPERS_set_flg */ 00222 00223 /* 00224 * イベントフラグのセット(非タスクコンテキスト用) 00225 */ 00226 #ifdef TOPPERS_iset_flg 00227 00228 ER 00229 iset_flg(ID flgid, FLGPTN setptn) 00230 { 00231 FLGCB *p_flgcb; 00232 QUEUE *p_queue; 00233 TCB *p_tcb; 00234 WINFO_FLG *p_winfo_flg; 00235 ER ercd; 00236 00237 LOG_ISET_FLG_ENTER(flgid, setptn); 00238 CHECK_INTCTX_UNL(); 00239 CHECK_FLGID(flgid); 00240 p_flgcb = get_flgcb(flgid); 00241 00242 i_lock_cpu(); 00243 p_flgcb->flgptn |= setptn; 00244 p_queue = p_flgcb->wait_queue.p_next; 00245 while (p_queue != &(p_flgcb->wait_queue)) { 00246 p_tcb = (TCB *) p_queue; 00247 p_queue = p_queue->p_next; 00248 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo); 00249 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn, 00250 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) { 00251 queue_delete(&(p_tcb->task_queue)); 00252 if (wait_complete(p_tcb)) { 00253 reqflg = true; 00254 } 00255 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) { 00256 break; 00257 } 00258 } 00259 } 00260 ercd = E_OK; 00261 i_unlock_cpu(); 00262 00263 error_exit: 00264 LOG_ISET_FLG_LEAVE(ercd); 00265 return(ercd); 00266 } 00267 00268 #endif /* TOPPERS_iset_flg */ 00269 00270 /* 00271 * イベントフラグのクリア 00272 */ 00273 #ifdef TOPPERS_clr_flg 00274 00275 ER 00276 clr_flg(ID flgid, FLGPTN clrptn) 00277 { 00278 FLGCB *p_flgcb; 00279 ER ercd; 00280 00281 LOG_CLR_FLG_ENTER(flgid, clrptn); 00282 CHECK_TSKCTX_UNL(); 00283 CHECK_FLGID(flgid); 00284 p_flgcb = get_flgcb(flgid); 00285 00286 t_lock_cpu(); 00287 p_flgcb->flgptn &= clrptn; 00288 ercd = E_OK; 00289 t_unlock_cpu(); 00290 00291 error_exit: 00292 LOG_CLR_FLG_LEAVE(ercd); 00293 return(ercd); 00294 } 00295 00296 #endif /* TOPPERS_clr_flg */ 00297 00298 /* 00299 * イベントフラグ待ち 00300 */ 00301 #ifdef TOPPERS_wai_flg 00302 00303 ER 00304 wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) 00305 { 00306 FLGCB *p_flgcb; 00307 WINFO_FLG winfo_flg; 00308 ER ercd; 00309 00310 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn); 00311 CHECK_DISPATCH(); 00312 CHECK_FLGID(flgid); 00313 CHECK_PAR(waiptn != 0U); 00314 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW); 00315 p_flgcb = get_flgcb(flgid); 00316 00317 t_lock_cpu(); 00318 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U 00319 && !queue_empty(&(p_flgcb->wait_queue))) { 00320 ercd = E_ILUSE; 00321 } 00322 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) { 00323 ercd = E_OK; 00324 } 00325 else { 00326 winfo_flg.waiptn = waiptn; 00327 winfo_flg.wfmode = wfmode; 00328 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG); 00329 wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg); 00330 dispatch(); 00331 ercd = winfo_flg.winfo.wercd; 00332 if (ercd == E_OK) { 00333 *p_flgptn = winfo_flg.flgptn; 00334 } 00335 } 00336 t_unlock_cpu(); 00337 00338 error_exit: 00339 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn); 00340 return(ercd); 00341 } 00342 00343 #endif /* TOPPERS_wai_flg */ 00344 00345 /* 00346 * イベントフラグ待ち(ポーリング) 00347 */ 00348 #ifdef TOPPERS_pol_flg 00349 00350 ER 00351 pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) 00352 { 00353 FLGCB *p_flgcb; 00354 ER ercd; 00355 00356 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn); 00357 CHECK_TSKCTX_UNL(); 00358 CHECK_FLGID(flgid); 00359 CHECK_PAR(waiptn != 0U); 00360 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW); 00361 p_flgcb = get_flgcb(flgid); 00362 00363 t_lock_cpu(); 00364 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U 00365 && !queue_empty(&(p_flgcb->wait_queue))) { 00366 ercd = E_ILUSE; 00367 } 00368 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) { 00369 ercd = E_OK; 00370 } 00371 else { 00372 ercd = E_TMOUT; 00373 } 00374 t_unlock_cpu(); 00375 00376 error_exit: 00377 LOG_POL_FLG_LEAVE(ercd, *p_flgptn); 00378 return(ercd); 00379 } 00380 00381 #endif /* TOPPERS_pol_flg */ 00382 00383 /* 00384 * イベントフラグ待ち(タイムアウトあり) 00385 */ 00386 #ifdef TOPPERS_twai_flg 00387 00388 ER 00389 twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout) 00390 { 00391 FLGCB *p_flgcb; 00392 WINFO_FLG winfo_flg; 00393 TMEVTB tmevtb; 00394 ER ercd; 00395 00396 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout); 00397 CHECK_DISPATCH(); 00398 CHECK_FLGID(flgid); 00399 CHECK_PAR(waiptn != 0U); 00400 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW); 00401 CHECK_TMOUT(tmout); 00402 p_flgcb = get_flgcb(flgid); 00403 00404 t_lock_cpu(); 00405 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U 00406 && !queue_empty(&(p_flgcb->wait_queue))) { 00407 ercd = E_ILUSE; 00408 } 00409 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) { 00410 ercd = E_OK; 00411 } 00412 else if (tmout == TMO_POL) { 00413 ercd = E_TMOUT; 00414 } 00415 else { 00416 winfo_flg.waiptn = waiptn; 00417 winfo_flg.wfmode = wfmode; 00418 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG); 00419 wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg, 00420 &tmevtb, tmout); 00421 dispatch(); 00422 ercd = winfo_flg.winfo.wercd; 00423 if (ercd == E_OK) { 00424 *p_flgptn = winfo_flg.flgptn; 00425 } 00426 } 00427 t_unlock_cpu(); 00428 00429 error_exit: 00430 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn); 00431 return(ercd); 00432 } 00433 00434 #endif /* TOPPERS_twai_flg */ 00435 00436 /* 00437 * イベントフラグの再初期化 00438 */ 00439 #ifdef TOPPERS_ini_flg 00440 00441 ER 00442 ini_flg(ID flgid) 00443 { 00444 FLGCB *p_flgcb; 00445 bool_t dspreq; 00446 ER ercd; 00447 00448 LOG_INI_FLG_ENTER(flgid); 00449 CHECK_TSKCTX_UNL(); 00450 CHECK_FLGID(flgid); 00451 p_flgcb = get_flgcb(flgid); 00452 00453 t_lock_cpu(); 00454 dspreq = init_wait_queue(&(p_flgcb->wait_queue)); 00455 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn; 00456 if (dspreq) { 00457 dispatch(); 00458 } 00459 ercd = E_OK; 00460 t_unlock_cpu(); 00461 00462 error_exit: 00463 LOG_INI_FLG_LEAVE(ercd); 00464 return(ercd); 00465 } 00466 00467 #endif /* TOPPERS_ini_flg */ 00468 00469 /* 00470 * イベントフラグの状態参照 00471 */ 00472 #ifdef TOPPERS_ref_flg 00473 00474 ER 00475 ref_flg(ID flgid, T_RFLG *pk_rflg) 00476 { 00477 FLGCB *p_flgcb; 00478 ER ercd; 00479 00480 LOG_REF_FLG_ENTER(flgid, pk_rflg); 00481 CHECK_TSKCTX_UNL(); 00482 CHECK_FLGID(flgid); 00483 p_flgcb = get_flgcb(flgid); 00484 00485 t_lock_cpu(); 00486 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue)); 00487 pk_rflg->flgptn = p_flgcb->flgptn; 00488 ercd = E_OK; 00489 t_unlock_cpu(); 00490 00491 error_exit: 00492 LOG_REF_FLG_LEAVE(ercd, pk_rflg); 00493 return(ercd); 00494 } 00495 00496 #endif /* TOPPERS_ref_flg */
Copyright © 2008 by Kijineko Inc.